ObservableCollection和BindingList之间的区别

时间:2010-11-26 10:57:39

标签: c# .net wpf observablecollection wpf-4.0

我想知道ObservableCollectionBindingList之间的区别,因为我已经使用了两者来通知Source中的任何添加/删除更改,但实际上我不知道何时更喜欢其他

为什么我会选择以下其中一种?

ObservableCollection<Employee> lstEmp = new ObservableCollection<Employee>();

BindingList<Employee> lstEmp = new BindingList<Employee>();

4 个答案:

答案 0 :(得分:270)

可以从UI更新ObservableCollection,就像任何集合一样。真正的区别是相当简单的:

ObservableCollection<T>实现INotifyCollectionChanged,它在集合发生变化时提供通知(你猜对了^^) 它允许绑定引擎在ObservableCollection更新时更新UI。

但是,BindingList<T>实现了IBindingList

IBindingList提供有关收藏更改的通知,但不仅如此。它提供了一大堆功能,UI可以根据更改提供更多内容而不仅仅是UI更新,例如:

  • 排序
  • 搜索
  • 通过工厂添加(AddNew成员函数)。
  • 只读列表(CanEdit属性)

ObservableCollection<T>

中没有所有这些功能

另一个区别是BindingList在项目实施INotifyPropertyChanged时会转发项目更改通知。如果某个项目引发了PropertyChanged个事件,则BindingList将会收到ListChangedEventListChangedType.ItemChangedOldIndex=NewIndex的加注项(如果项目已被替换,OldIndex=-1 1}})。 ObservableCollection不会转发项目通知。

请注意,在Silverlight中,BindingList不作为选项提供:但是,如果我记得很清楚,您可以使用ObservableCollectionICollectionView(和IPagedCollectionView。)< / p>

答案 1 :(得分:22)

实际区别在于BindingList用于WinForms,而ObservableCollection用于WPF。

从WPF的角度来看,BindingList没有得到适当的支持,除非你真的不得不在WPF项目中使用它。

答案 2 :(得分:1)

ObservableCollectionBindingList之间的另一个重大差异非常方便,可以作为该主题的出价决策因素:

BindingList列表更改处理程序:

BindingList List Change

ObservableCollection收藏品更改:

ObervableCollection Collection Changed

  

以上简要说明:如果BindingList中的商品属性发生了变化,ListChanged活动会为您提供完整的详细信息   属性(在PropertyDescriptor中)和ObservableCollection不会给你这个。事实上   ObservableCollection不会引发属性的更改事件   改变了一个项目。

以上结论是关于在模型类中实现的INotifyPropertyChanged。默认情况下,如果项目中的属性发生更改,则不会引发更改的事件。

答案 3 :(得分:1)

已接受的答案已经提到了最重要的区别,例如功能和有关所包含元素的更改通知,但还有更多区别,还值得一提:

性能

调用AddNew时,BindingList<T>通过IndexOf查找来搜索添加的项目。并且,如果T实现了INotifyPropertyChanged,则IndexOf也会搜索已更改元素的索引(尽管只要同一项目重复更改,就不会有新的查找)。如果您在集合中存储了数千个元素,则ObservableCollection<T>(或具有O(1)查找成本的自定义IBindingList实现)会更可取。

完整度

  • IBindingList接口是一个很大的接口(也许不是最干净的设计),并且允许实现者仅实现其功能的一部分。例如,AllowNewSupportsSortingSupportsSearching属性告诉您是否可以分别使用AddNewApplySortFind方法。 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是引用类型,则对元素的更改将从原始集合中可见,但是集合本身将不会更新。