ObservableCollection 和 BindingList 之间的区别

发布于 2024-10-05 02:40:56 字数 374 浏览 8 评论 0原文

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

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

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

或者

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

I want to know the difference between ObservableCollection and BindingList because I've used both to notify for any add/delete change in Source, but I actually do not know when to prefer one over the other.

Why would I choose one of the following over the other?

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

or

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

天邊彩虹 2024-10-12 02:40:56

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

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

但是,BindingList 实现 IBindingList

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

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

所有这些功能在 ObservableCollection 中均不可用。

另一个区别是 BindingList 在其项实现 INotifyPropertyChanged 时中继项更改通知代码>.如果某个项目引发 PropertyChanged 事件,则 BindingList 将接收该事件,并引发 ListChangedEvent 以及 ListChangedType.ItemChangedOldIndex=NewIndex(如果替换了某个项目,OldIndex=-1)。 ObservableCollection 不会转发项目通知。

请注意,在 Silverlight 中,BindingList 不可用作选项:但是,您可以使用 ObservableCollectionICollectionView(以及 IPgedCollectionView代码>如果我没记错的话)。

An ObservableCollection can be updated from UI exactly like any collection. The true difference is rather straightforward:

ObservableCollection<T> implements INotifyCollectionChanged which provides notification when the collection is changed (you guessed ^^)
It allows the binding engine to update the UI when the ObservableCollection is updated.

However, BindingList<T> implements IBindingList.

IBindingList provides notification on collection changes, but not only that. It provides a whole bunch of functionality which can be used by the UI to provide a lot more things than only UI updates according to changes, like:

  • Sorting
  • Searching
  • Add through factory (AddNew member function).
  • Readonly list (CanEdit property)

All these functionalities are not available in ObservableCollection<T>

Another difference is that BindingList relays item change notifications when its items implement INotifyPropertyChanged. If an item raises a PropertyChanged event, the BindingList will receive it an raises a ListChangedEvent with ListChangedType.ItemChanged and OldIndex=NewIndex (if an item was replaced, OldIndex=-1). ObservableCollection doesn't relay item notifications.

Note that in Silverlight, BindingList is not available as an option: You can however use ObservableCollections and ICollectionView (and IPagedCollectionView if I remember well).

撩发小公举 2024-10-12 02:40:56

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

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

The practical difference is that BindingList is for WinForms, and ObservableCollection is for WPF.

From a WPF perspective, BindingList isnt properly supported, and you would never really use it in a WPF project unless you really had to.

背叛残局 2024-10-12 02:40:56

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

性能

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

完整性

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

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

复制与包装

ObservableCollectionBindingList 都有一个构造函数,它接受已存在的列表。尽管它们在由另一个集合实例化时的行为有所不同:

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

The most important differences such as features and change notifications about the contained elements are already mentioned by the accepted answer but there are more, which also worth mentioning:

Performance

When AddNew is called, BindingList<T> searches for the added item by an IndexOf lookup. And if T implements INotifyPropertyChanged the index of a changed element is also searched by IndexOf (though there is no new lookup as long as the same item changes repeatedly). If you store thousands of elements in the collection, then ObservableCollection<T> (or a custom IBindingList implementation with O(1) lookup cost) can be more preferable.

Completeness

  • 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.

Copy vs. wrapping

Both ObservableCollection<T> and BindingList<T> have a constructor, which accepts an already existing list. Though they behave differently when they are instantiated by another collection:

  • 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.
似狗非友 2024-10-12 02:40:56

ObservableCollectionBindingList 之间还有一个巨大差异,很方便,并且可以成为该主题的出价决策因素:

BindingList 列表更改处理程序:

BindingList 列表更改

ObservableCollection 集合更改:

ObervableCollection 集合已更改

上述简要说明:如果 BindingList 中的项目属性发生更改,ListChanged 事件将为您提供完整的详细信息
of property(in PropertyDescriptor) 和 ObservableCollection 不会给你这个。实际上
ObservableCollection 不会引发属性的更改事件
更改了一个项目。

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

One More big difference between ObservableCollection and BindingList that comes handy, and can be a bid decision factor on the topic :

BindingList List Change Handler:

BindingList List Change

ObservableCollection Collection change:

ObervableCollection Collection Changed

Brief of Above: If a property of an item is changed in BindingList, the ListChanged event will give you complete details
of property(in PropertyDescriptor) and ObservableCollection won't give you that. In fact
ObservableCollection will not raise change event for a property
changed in an item.

Above conclusion are in regards of INotifyPropertyChanged implemented in model classes. By default none raises the changed event if a property is changed in an item.

半衾梦 2024-10-12 02:40:56

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

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

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

另请注意,使用 (ToBindingList 实体框架中的扩展),以及返回的(派生的)BindingList 实现了普通功能所缺乏的功能,例如排序。

Both have advantages and drawbacks that take some time to discover.

I had some trouble with BindingList because the change notification event occurs only after an item has been removed and provides only an index (which means that you have to keep track of which object was at which location if you have implemented some post-removal mechanism). ObservableCollection, on the other hand, gives you a list of the removed items.

BindingList has a handy AddNew() method that allows a derived class to implement a factory pattern, e.g. to initialize the new items with values depending on the parent collection (for instance, a foreign key to the parent if the collection contains child items).

Note also that it is very easy to get a BindingList from an ObservableCollection, using (ToBindingList extension in Entity Framework), and that the returned (derived) BindingList implements features, like sorting, that lack in the plain vanilla one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文