首页 文章

ObservableCollection和BindingList之间的区别

提问于
浏览
216

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

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

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

要么

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

4 回答

  • 20

    可以从UI更新 ObservableCollection ,与任何集合完全相同 . 真正的区别是相当简单的:

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

    但是, BindingList<T> 实现 IBindingList .

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

    • 排序

    • 正在搜索

    • 通过工厂添加(AddNew成员函数) .

    • 只读列表(CanEdit属性)

    ObservableCollection<T> 无法提供所有这些功能

    另一个区别是 BindingList 在项目实现 INotifyPropertyChanged 时中继项目更改通知 . 如果一个项目引发一个 PropertyChanged 事件, BindingList 将收到一个 ListChangedEvent ,其中包含 ListChangedType.ItemChangedOldIndex=NewIndex (如果项目已被替换, OldIndex=-1 ) . ObservableCollection 不会中继项目通知 .

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

  • 1

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

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

  • 0

    ObservableCollectionBindingList 之间的另一个 big difference 方便,并且可以作为该主题的出价决定因素:

    BindingList List Change Handler:

    BindingList List Change

    ObservableCollection Collection change:

    ObervableCollection Collection Changed

    上述简介:如果在BindingList中更改了项的属性,则ListChanged事件将为您提供属性的完整详细信息(在PropertyDescriptor中),而ObservableCollection将不会为您提供 . 实际上,ObservableCollection不会为项目中更改的属性引发更改事件 .

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

  • 264

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

    Performance

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

    Completeness

    • IBindingList 接口是一个巨大的接口(可能不是最干净的设计),并允许实现者只实现其功能的一个子集 . 例如, AllowNewSupportsSortingSupportsSearching 属性分别指示是否可以使用 AddNewApplySortFind 方法 . 人们经常会惊讶于 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 是引用类型,则元素的更改将从原始集合中可见,但集合本身将不会更新 .

相关问题