Answers:
一个ObservableCollection
可以从用户界面酷似任何集合进行更新。真正的区别非常简单:
ObservableCollection<T>
实现INotifyCollectionChanged
在集合更改时提供通知的实现(您猜对了^^),它允许绑定引擎在更新时更新UI ObservableCollection
。
但是,BindingList<T>
工具IBindingList
。
IBindingList
提供有关集合更改的通知,但不仅限于此。它提供了一整套功能,UI可以使用这些功能提供很多功能,而不仅仅是根据更改进行UI更新,例如:
所有这些功能在 ObservableCollection<T>
另一个不同之处是,BindingList
在实现项目更改时,中继项目更改通知INotifyPropertyChanged
。如果某个项目引发了一个PropertyChanged
事件,则BindingList
它将收到一个ListChangedEvent
带有ListChangedType.ItemChanged
和的引发a OldIndex=NewIndex
(如果已替换了一个项目OldIndex=-1
)。ObservableCollection
不中继项目通知。
请注意,在Silverlight中,BindingList
不是可选选项:但是,您可以使用ObservableCollection
s和ICollectionView
(并且IPagedCollectionView
我记得很好)。
BindingList
过时了吗?
实际的区别在于BindingList用于WinForms,而ObservableCollection用于WPF。
从WPF角度来看,不正确地支持BindingList,除非您确实需要,否则您永远不会在WPF项目中真正使用它。
公认的答案已经提到了最重要的区别,例如功能和有关所包含元素的更改通知,但还有更多区别,还值得一提:
性能
当AddNew
被调用时,BindingList<T>
通过对添加的项目搜索IndexOf
查找。并且如果T
实现INotifyPropertyChanged
,还可以搜索已更改元素的索引IndexOf
(尽管只要同一项目重复更改,就不会有新的查找)。如果在集合中存储了数千个元素,则ObservableCollection<T>
(或IBindingList
使用O(1)查找成本的自定义实现)可能会更可取。
完整性
该IBindingList
接口是一个巨大的接口(可能不是最干净的设计),并且允许实现者仅实现其功能的一部分。例如,AllowNew
,SupportsSorting
和SupportsSearching
属性告诉是否AddNew
,ApplySort
和Find
方法可以分别使用,。人们常常会惊讶于它BindingList<T>
本身不支持排序。实际上,它提供了一些虚拟方法,让派生类添加缺少的功能。该DataView
班是一个完整的例子IBindingList
实施; 但是,它并非首先用于类型化的集合。BindingSource
WinForms中的类是一个混合示例:如果包装另一个IBindingList
支持排序的实现,则它支持排序。
ObservableCollection<T>
已经是INotifyCollectionChanged
接口的完整实现(只有一个事件)。它也具有虚拟成员,但ObservableCollection<T>
通常出于与其基Collection<T>
类相同的原因而派生:用于自定义添加/删除项(例如,在数据模型集合中)而不是调整绑定功能。
复制与包装
双方ObservableCollection<T>
并BindingList<T>
有一个构造函数,它接受一个已经存在的列表。尽管它们在被另一个集合实例化时的行为有所不同:
BindingList<T>
充当所提供列表的可观察包装器,并且在上执行的更改BindingList<T>
也将反映在基础集合上。ObservableCollection<T>
另一方面,将新List<T>
实例传递给基本Collection<T>
构造函数,并将原始集合的元素复制到此新列表中。当然,如果T
是引用类型,则对元素的更改将从原始集合中可见,但集合本身不会被更新。多一个很大的区别之间ObservableCollection
,并BindingList
自带方便,并且可以在该主题的投标决策的因素:
BindingList
列表更改处理程序:
ObservableCollection
集合变更:
上面的内容简介:如果某项的属性在中更改
BindingList
,则该ListChanged
事件将为您提供该属性的完整详细信息(在PropertyDescriptor中),ObservableCollection
而不会提供给您。实际上,ObservableCollection
不会为项目中更改的属性引发更改事件。
以上结论是关于INotifyPropertyChanged
模型类中实现的。默认情况下,如果项目中的属性发生更改,则none不会引发更改事件。