ObservableCollection和BindingList之间的区别

Azh*_*har 234 .net c# wpf observablecollection wpf-4.0

我想知道它们之间的区别ObservableCollection,BindingList因为我已经使用了两者来通知Source中的任何添加/删除更改,但实际上我不知道何时更喜欢一个而不是另一个.

为什么我会选择以下其中一个而不是另一个?

ObservableCollection<Employee> lstEmp = new ObservableCollection<Employee>();
Run Code Online (Sandbox Code Playgroud)

要么

BindingList<Employee> lstEmp = new BindingList<Employee>();
Run Code Online (Sandbox Code Playgroud)

Eil*_*aee 277

一个ObservableCollection可以从用户界面酷似任何集合进行更新.真正的区别是相当简单:

ObservableCollection<T>INotifyCollectionChanged在更改集合时提供通知的实现(您猜到了^^)它允许绑定引擎在更新时更新UI ObservableCollection.

但是,BindingList<T>工具IBindingList.

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

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

所有这些功能都不可用 ObservableCollection<T>

另一个区别是,BindingList当项目实现时,中继项目更改通知INotifyPropertyChanged.如果一个项目提出了一个PropertyChanged事件时,BindingList会收到一个提出了一个ListChangedEventListChangedType.ItemChangedOldIndex=NewIndex(如果一个项目被换下,OldIndex=-1).ObservableCollection不会中继项目通知.

请注意,在Silverlight中,BindingList不作为选项提供:但是您可以使用ObservableCollections和ICollectionView(IPagedCollectionView如果我记得很清楚的话).

  • 虽然这个答案中的信息是正确的,但任何WPF用户都应该注意:BindingList没有实现INotifyCollectionChanged,如果绑定到控件的ItemsSource属性,将导致内存泄漏.ObservableCollection确实实现了接口,不会导致任何此类泄漏. (5认同)
  • 另外需要考虑的是性能,请参阅:http://www.themissingdocs.net/wordpress/?p = 465 (4认同)
  • 谢谢,我不知道 BindingList 的实际实现。我倾向于使用 ObservableCollection 和 ICollectionView (2认同)

Dea*_*alk 24

实际的区别是BindingList用于WinForms,而ObservableCollection用于WPF.

从WPF的角度来看,BindingList没有得到适当的支持,除非你真的需要,否则你永远不会在WPF项目中真正使用它.

  • 为什么"不支持"?ViewManager(内部)位于PresentationFramework程序集中并支持它.例如,将它绑定到ItemsControl,并遵守更改通知(即添加和删除项目).如果它是WinForms具体应该不是更好地放在Forms命名空间? (27认同)
  • 同意David也是,我经常在WPF中使用BindingList,因为ObservableCollection不会从其项目中冒出属性更改通知. (13认同)
  • 与David同意,它位于System.Collections命名空间中,因此WPF应该完全支持它.WPF只是一种不同的UI布局方式. (7认同)
  • 举一个"not supportet"的例子:我刚刚在我的WPF应用程序中发现内存泄漏,这是由一些未实现INotifyCollectionChanged的BindingLists引起的 (3认同)

Gyö*_*zeg 9

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

表现

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

完整性

  • IBindingList接口是一个巨大的接口(可能不是最干净的设计),并且允许实现者仅实现其功能的一个子集。例如,AllowNewSupportsSortingSupportsSearching属性告诉是否AddNewApplySortFind方法可以分别使用,。它BindingList<T>本身不支持排序,这常常让人们感到惊讶。实际上,它提供了一些虚拟方法,让派生类添加缺少的功能。该DataView班是一个完整的例子IBindingList实施; 但是,它首先不适用于类型化集合。BindingSourceWinForms 中的类是一个混合示例:如果它包装了另一个IBindingList支持排序的实现,则它支持排序。

  • ObservableCollection<T>已经是INotifyCollectionChanged接口的完整实现(只有一个事件)。它也有虚拟成员,但ObservableCollection<T>通常出于与其基Collection<T>类相同的原因派生:用于自定义添加/删除项目(例如,在数据模型集合中)而不是调整绑定功能。

复制与包装

双方ObservableCollection<T>BindingList<T>有一个构造函数,它接受一个已经存在的列表。尽管当它们被另一个集合实例化时,它们的行为有所不同:

  • BindingList<T>充当提供的列表的可观察包装器,对 执行的更改BindingList<T>也将反映在基础集合上。
  • ObservableCollection<T>另一方面,将一个新List<T>实例传递给基本Collection<T>构造函数,并将原始集合的元素复制到这个新列表中。当然,如果T是引用类型,则元素上的更改将从原始集合中可见,但集合本身不会更新。