252

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

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

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

或者

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

5 回答 5

291

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

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

但是,BindingList<T>实现IBindingList.

IBindingList提供有关集合更改的通知,但不仅如此。它提供了一大堆功能,UI 可以使用这些功能提供更多的东西,而不仅仅是根据更改更新 UI,例如:

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

所有这些功能在ObservableCollection<T>

另一个区别是BindingList在其项目实施时中继项目更改通知INotifyPropertyChanged。如果一个项目引发了一个PropertyChanged事件,则将接收它并BindingList引发一个ListChangedEvent与(如果项目被替换,)。不中继项目通知。ListChangedType.ItemChangedOldIndex=NewIndexOldIndex=-1ObservableCollection

请注意,在 Silverlight 中,BindingList不能作为选项使用:但是您可以使用ObservableCollections 和ICollectionViewIPagedCollectionView如果我没记错的话)。

于 2010-11-26T11:19:21.800 回答
29

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

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

于 2010-11-26T11:34:25.077 回答
9

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

表现

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

完整性

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

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

复制与包装

两者ObservableCollection<T>都有BindingList<T>一个构造函数,它接受一个已经存在的列表。尽管它们在被另一个集合实例化时表现不同:

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

和之间的另一个更大的区别很方便,并且可以成为该主题的出价决策因素:ObservableCollectionBindingList

BindingList列表更改处理程序:

BindingList 列表更改

ObservableCollection收藏变化:

ObervableCollection 集合已更改

上面的简要说明:如果某个项目的属性在 中发生更改BindingList,该ListChanged事件将为您提供属性的完整详细信息(在 PropertyDescriptor 中)并且ObservableCollection不会给您。事实上 ObservableCollection,不会为项目中更改的属性引发更改事件。

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

于 2016-02-12T05:32:42.680 回答
0

两者都有优点和缺点,需要一些时间才能发现。

我在使用 BindingList 时遇到了一些问题,因为更改通知事件仅在删除项目发生并且仅提供索引(这意味着如果您实施了一些删除后机制,则必须跟踪哪个对象位于哪个位置) . 另一方面,ObservableCollection 为您提供已删除项目的列表。

BindingList 有一个方便的 AddNew() 方法,它允许派生类实现工厂模式,例如使用取决于父集合的值(例如,如果集合包含子项,则为父项的外键)初始化新项。

另请注意,使用(实体框架中的 ToBindingList 扩展)从 ObservableCollection 获取 BindingList 非常容易,并且返回的(派生的)BindingList 实现了普通香草中缺乏的功能,如排序。

于 2021-12-13T17:01:22.593 回答