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