I am just now getting my toes wet in WPF after several years of working in ASP.Net exclusively. The problem I am currently struggling with is that I have a custom collection class which I need to bind to a listbox. Everything seems to be working except for removing an item from the collection. When I try to I get the error: “Collection Remove event must specify item position.”
The catch is that this collection does not use indexes so I am not seeing a way to specify the position and so far Google has failed to show me a workable solution…
The class is defined to implement ICollection<>
and INotifyCollectionChanged
. My internal items container is a Dictionary
which uses the item’s Name(string) value for a key. Aside from the methods defined by these two interfaces, this collection has an indexer that allows items to be accessed by Name, and overrides for the Contains
and Remove
methods so that they can also be called with the item Name. This is working for Adds and Edits but throws the above exception when I try to remove.
Here is an excerpt of the relevant code:
class Foo
{
public string Name
{
get;
set;
}
}
class FooCollection : ICollection<Foo>, INotifyCollectionChanged
{
Dictionary<string, Foo> Items;
public FooCollection()
{
Items = new Dictionary<string, Foo>();
}
#region ICollection<Foo> Members
//***REMOVED FOR BREVITY***
public bool Remove(Foo item)
{
return this.Remove(item.Name);
}
public bool Remove(string name)
{
bool Value = this.Contains(name);
if (Value)
{
NotifyCollectionChangedEventArgs E = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, Items[name]);
Value = Items.Remove(name);
if (Value)
{
RaiseCollectionChanged(E);
}
}
return Value;
}
#endregion
#region INotifyCollectionChanged Members
public event NotifyCollectionChangedEventHandler CollectionChanged;
private void RaiseCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (CollectionChanged != null)
{
CollectionChanged(this, e);
}
}
#endregion
}
Your custom collection seems like a re-invention of KeyedCollection<TKey,TItem>
, which internally uses a dictionary, and has indexes. The indexer for int
indexes can get hidden if TKey
is int
or int
-based enum, but this can be fixed.
As for making KeyedCollection
work with WPF, I found this article, in which he basically makes an ObservableKeyedCollection<TKey,TItem>
by implementing INotifyCollectionChanged
and overriding SetItem()
, InsertItem()
, ClearItems()
, and RemoveItem()
, along with adding AddRange()
and passing a Func<TItem,TKey>
to the constructor for getting the TKey
from a TItem
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With