Ale*_*all 7 c# wpf observablecollection hashset
我正在使用ListBox来维护WPF应用程序中的项目列表.ListBox数据源是一个包含在ObservableCollection中的HashSet.即,我有以下代码:
this.shackSet = new ObservableCollection<Shack>(new HashSet<Shack>());
this.shackListing.ItemsSource = this.shackSet;
Run Code Online (Sandbox Code Playgroud)
...其中shackListing是一个ListBox控件,另一个是ICollection中的shackSet.但是,每当我在添加第一个项目后向shackSet添加任何内容时,我会在ListBox中看到多个项目.即,就像新添加的项目被添加到列表中一样,无论它们是否已添加到集合中.当我看到ICollection的签名#Add:
void Add(T obj);
Run Code Online (Sandbox Code Playgroud)
...和HashSet #Add:
bool Add(T obj);
Run Code Online (Sandbox Code Playgroud)
......这使我相信有一个影响包裹HashSets其中新添加的项目被添加到列表框,无论是因为的ObservableCollection没有告诉该对象是否实际添加到收藏垫层的方式中的错误,因为ICollection的#返回类型添加无效.其他人可以证实这一点吗?
当您使用另一个集合创建一个新的ObservableCollection时,您没有包装该集合,而是创建一个新的集合,其中传递的集合的所有项都被复制到ObservableCollection.如果您想将ObservableCollection用于DataBinding的唯一目的,那么您可以将其绑定到WPF中的任何IEnumerable.这不幸地有一个缺点,即WPF不会总是正确地拾取绑定集合的更改.如果这是一个问题,您可能需要创建自己的obeservable hashset:
public class ObservableHashSet<T> : ObservableCollection<T>
{
protected override void InsertItem(int index, T item)
{
if (Contains(item))
{
throw new ItemExistsException(item);
}
base.InsertItem(index, item);
}
protected override void SetItem(int index, T item)
{
int i = IndexOf(item);
if (i >= 0 && i != index)
{
throw new ItemExistsException(item);
}
base.SetItem(index, item);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:AS已经指出,你不能从HashSet继承来实现INotifyCollectionChanged.但是,如果你看一下HashSet类的代码(使用Reflector),那么很难自己模仿这个功能.