我想知道ObservableCollection和BindingList之间的区别,因为我已经使用它们来通知源中的任何添加/删除更改,但我实际上不知道什么时候更喜欢其中一个。
为什么我要选择下面的一个而不是另一个呢?
ObservableCollection<Employee> lstEmp = new ObservableCollection<Employee>();
or
BindingList<Employee> lstEmp = new BindingList<Employee>();
一个ObservableCollection可以像任何集合一样从UI更新。真正的区别很简单:
ObservableCollection<T>实现INotifyCollectionChanged,它在集合发生变化时提供通知(你猜的是^^)
它允许绑定引擎在observableccollection更新时更新UI。
而BindingList<T>实现了IBindingList。
IBindingList提供关于集合更改的通知,但不仅如此。它提供了一大堆的功能,可以被UI使用来提供更多的东西,而不仅仅是UI根据变化更新,比如:
排序
搜索
通过工厂添加(AddNew成员函数)。
只读列表(CanEdit属性)
所有这些功能在ObservableCollection<T>中都不可用
另一个区别是,当BindingList的项实现INotifyPropertyChanged时,BindingList转发项更改通知。如果一个项目引发了一个PropertyChanged事件,BindingList将接收它并引发一个带有ListChangedType的ListChangedEvent。ItemChanged和OldIndex=NewIndex(如果一个项目被替换,OldIndex=-1)。ObservableCollection不传递项目通知。
注意,在Silverlight中,BindingList是不可用的选项:你可以使用ObservableCollections和ICollectionView(和IPagedCollectionView,如果我没记错的话)。
最重要的区别,比如包含元素的特性和更改通知,已经在公认的答案中提到了,但还有更多,也值得一提:
性能
当AddNew被调用时,BindingList<T>通过IndexOf查找来搜索添加的项。如果T实现了INotifyPropertyChanged,更改后的元素的索引也会被IndexOf搜索(尽管只要同一项重复更改,就不会有新的查找)。如果您在集合中存储了数千个元素,那么ObservableCollection<T>(或具有O(1)查找代价的自定义IBindingList实现)可能更可取。
完整性
The IBindingList interface is a huge one (maybe not the cleanest design) and allows the implementors to implement only a subset of its features. For example, the AllowNew, SupportsSorting and SupportsSearching properties tell whether AddNew, ApplySort and Find methods can be used, respectively. It often surprises people that BindingList<T> itself does not support sorting. Actually it provides some virtual methods letting the derived classes add the missing features. The DataView class is an example for a full IBindingList implementation; however, it is not for typed collections in the first place. And the BindingSource class in WinForms is a hybrid example: it supports sorting if it wraps another IBindingList implementation, which supports sorting.
ObservableCollection<T> is already a complete implementation of the INotifyCollectionChanged interface (which has only a single event). It also has virtual members but ObservableCollection<T> is typically derived for the same reason as its base Collection<T> class: for customizing add/remove items (eg. in a data model collection) rather than adjusting binding features.
复制vs.换行
ObservableCollection<T>和BindingList<T>都有一个构造函数,它接受一个已经存在的列表。尽管当它们被另一个集合实例化时表现不同:
BindingList<T> acts as an observable wrapper for the provided list, and the changes performed on the BindingList<T> will be reflected on the underlying collection as well.
ObservableCollection<T> on the other hand passes a new List<T> instance to the base Collection<T> constructor and copies the elements of the original collection into this new list. Of course, if T is a reference type changes on the elements will be visible from the original collection but the collection itself will not be updated.