我想知道ObservableCollection
和BindingList
之间的区别,因为我已经使用了两者来通知Source中的任何添加/删除更改,但实际上我不知道何时更喜欢其他
为什么我会选择以下其中一种?
ObservableCollection<Employee> lstEmp = new ObservableCollection<Employee>();
或
BindingList<Employee> lstEmp = new BindingList<Employee>();
答案 0 :(得分:270)
可以从UI更新ObservableCollection
,就像任何集合一样。真正的区别是相当简单的:
ObservableCollection<T>
实现INotifyCollectionChanged
,它在集合发生变化时提供通知(你猜对了^^)
它允许绑定引擎在ObservableCollection
更新时更新UI。
但是,BindingList<T>
实现了IBindingList
。
IBindingList
提供有关收藏更改的通知,但不仅如此。它提供了一大堆功能,UI可以根据更改提供更多内容而不仅仅是UI更新,例如:
ObservableCollection<T>
另一个区别是BindingList
在项目实施INotifyPropertyChanged
时会转发项目更改通知。如果某个项目引发了PropertyChanged
个事件,则BindingList
将会收到ListChangedEvent
加ListChangedType.ItemChanged
和OldIndex=NewIndex
的加注项(如果项目已被替换,OldIndex=-1
1}})。 ObservableCollection
不会转发项目通知。
请注意,在Silverlight中,BindingList
不作为选项提供:但是,如果我记得很清楚,您可以使用ObservableCollection
和ICollectionView
(和IPagedCollectionView
。)< / p>
答案 1 :(得分:22)
实际区别在于BindingList用于WinForms,而ObservableCollection用于WPF。
从WPF的角度来看,BindingList没有得到适当的支持,除非你真的不得不在WPF项目中使用它。
答案 2 :(得分:1)
ObservableCollection
和BindingList
之间的另一个重大差异非常方便,可以作为该主题的出价决策因素:
BindingList
列表更改处理程序:
ObservableCollection
收藏品更改:
以上简要说明:如果
BindingList
中的商品属性发生了变化,ListChanged
活动会为您提供完整的详细信息 属性(在PropertyDescriptor中)和ObservableCollection
不会给你这个。事实上ObservableCollection
不会引发属性的更改事件 改变了一个项目。
以上结论是关于在模型类中实现的INotifyPropertyChanged
。默认情况下,如果项目中的属性发生更改,则不会引发更改的事件。
答案 3 :(得分:1)
已接受的答案已经提到了最重要的区别,例如功能和有关所包含元素的更改通知,但还有更多区别,还值得一提:
性能
调用AddNew
时,BindingList<T>
通过IndexOf
查找来搜索添加的项目。并且,如果T
实现了INotifyPropertyChanged
,则IndexOf
也会搜索已更改元素的索引(尽管只要同一项目重复更改,就不会有新的查找)。如果您在集合中存储了数千个元素,则ObservableCollection<T>
(或具有O(1)查找成本的自定义IBindingList
实现)会更可取。
完整度
IBindingList
接口是一个很大的接口(也许不是最干净的设计),并且允许实现者仅实现其功能的一部分。例如,AllowNew
,SupportsSorting
和SupportsSearching
属性告诉您是否可以分别使用AddNew
,ApplySort
和Find
方法。 BindingList<T>
本身不支持排序常常让人感到惊讶。实际上,它提供了一些虚拟方法,让派生类添加缺少的功能。 DataView
类是完整IBindingList
实现的示例;但是,它并非首先用于类型化的集合。 WinForms中的BindingSource
类是一个混合示例:如果包装了另一个支持排序的IBindingList
实现,则它支持排序。
ObservableCollection<T>
已经是INotifyCollectionChanged
接口(只有一个事件)的完整实现。它也具有虚拟成员,但是ObservableCollection<T>
通常是基于与其基类Collection<T>
相同的原因派生的:用于自定义添加/删除项(例如,在数据模型集合中)而不是调整绑定功能。 / p>
复制与包装
ObservableCollection<T>
和BindingList<T>
都有一个构造函数,该构造函数接受一个已经存在的列表。尽管它们在被另一个集合实例化时的行为有所不同:
BindingList<T>
充当可观察的包装器,并且在BindingList<T>
上执行的更改也将反映在基础集合上。ObservableCollection<T>
将新的List<T>
实例传递给基本的Collection<T>
构造函数,并将原始集合的元素复制到此新列表中。当然,如果T
是引用类型,则对元素的更改将从原始集合中可见,但是集合本身将不会更新。