我正在研究为什么 ObservableCollection/ListCollectionView/CollectionView
在使用 IList 参数调用 CollectionChanged 时引发 NotSuportedException。
//Throws an exception
private void collectionChanged_Removed(IList items)
{
if (CollectionChanged != null)
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, items));
}
我找到了几个讨论这个主题的网页,他们建议使用 Reset
功能来强制完全重绘 UI,或者只是简单地为每个项目调用 CollectionChanged
或一些更有创意的方式:http://geekswithblogs.net/NewThingsILearned/archive/2008/01/16/listcollectionviewcollectionview-doesnt-support-notifycollectionchanged-with-multiple-items.aspx
我就是找不到原因? 对我来说,我不明白为什么会这样。
我们所有人在开发周期的某个时刻都会遇到这种缺少的功能,因为当您想要快速添加多个项目时,Add 方法会产生大量开销, 将随时实现(.Net 5、C# 6...)。
编辑:
在我的具体情况下,我编写了自己的类(class):
public class ObservableList<T> : IList<T>, IList, IEnumerable<T>,
INotifyCollectionChanged
{
public event NotifyCollectionChangedEventHandler CollectionChanged;
//other stuff...
}
并且仍然抛出上述 NotSupportedException。
最佳答案
受 VirtualBlackFox 回答的启发,我深入了解了 ILSpy 中的 CollectionView
类。似乎 为什么 缺乏对 Range 操作的支持的主要原因是 CollectionView
在内部使用更改日志来集中管理所有类型的未决更改并在每个/项目的基础。
就其目的而言,CollectionView
可以存储 1000 条记录,这些记录与表示其基础数据的多个 UI 控件同时使用。因此,添加或删除记录必须在原子基础上完成,以维护访问 View 信息的 UI 控件的完整性。如果不将 CollectionView 的分组、排序和过滤功能传递到使用它的 UI 控件,您就无法使用批量更改事件将增量更改与多个 UI 订阅者同步。
CollectionView
也派生自 System.Windows.Threading.Dispatcher
,因此该问题可能与它如何管理其线程上的工作项有关。调用路径包括一个 protected ProcessCollectionChanged
方法,该方法专门处理 UI 线程上的各个更改。因此,更新范围可能会干扰它用来与使用它的 UI 元素进行交互的整个线程模型。
我完全同意让 CollectionView
的消费者将 IList
传递给 NotifyCollectionChangedEventArgs
是愚蠢的。它特别拒绝长度为 != 1 的任何内容,并在内部对 args.NewItems[0]
进行硬编码。
关于c# - CollectionChanged 和 IList of Items - 为什么困难,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21557368/