【问题标题】:ObservableCollection(Of T) vs BindingList(Of T)?ObservableCollection(Of T) vs BindingList(Of T)?
【发布时间】:2010-10-02 02:25:56
【问题描述】:

在过去的两年里,我开发了一些基于数据的 Winforms 应用程序,一切正常。此应用程序建立在层(数据访问、业务逻辑和 UI)之上。对于业务逻辑,我所有的对象都继承自一个名为 BaseEntity 的基类,其定义如下(有一些自定义对象和接口,结合框架元素):

Public MustInherit Class BaseEntity
    Inherits SerializableObject
    Implements IEntity
    Implements IComparer,  _
               IEditableObject,  _
               INotifyPropertyChanging, INotifyPropertyChanged,  _
               IApplicationSecurity
End Class

在同一个核心库中,我有一个通用基础集合 BaseEntityCollection。这些集合允许我为每个对象定义他相关的强类型集合,这在基于数据的应用程序中非常有趣。这是它的基本定义:

 Public MustInherit Class BaseEntityCollection(Of T As BaseEntity)
    Inherits BindingList(Of T)
    Implements IEntityCollection
    Implements INotifyPropertyChanged, INotifyPropertyChanging, ICopyable(Of T)
    Implements IDisposable
    Implements ISerializable
  End Class

如您所见,我使用了 Winforms 中正确数据绑定所需的所有内容:

  • 对象的 INotifyPropertyChanged、INotifyPropertyChanging、IEditableObject。
  • 我的集合基于 BindingList(Of T) 的集合。

我对新技术也很感兴趣,所以我最近看了一些关于 WPF 的网络广播。在这些网络广播中,它们用作收集和数据绑定支持 ObservableCollection(Of T) 的基类。

我正在考虑将我的一些应用程序从 Winforms 迁移到 UI 层的 WPF。

我的问题是,对于我的业务逻辑,是基于 BindingList(Of T) 更好地保留我的集合,还是应该更改我的基本集合类以使其继承自 ObservableCollection(Of T)。我想为我的所有项目保留一个独特的基础集合,它也可以在 Winforms 应用程序、WPF 应用程序或 ASP.NET 中使用。 我还在我的项目中使用 Linq to Objects,因此我的项目仅基于框架 2.0 并不受限制。

【问题讨论】:

    标签: winforms data-binding observablecollection bindinglist


    【解决方案1】:

    克莱伯,

    我会保留 BindingList,因为 BindingList 比 ObservableCollection 支持更多的接口和更丰富的功能。 例如:

    1. BindingList 实现 T 的 IList,而 ObservableCollection 没有。
    2. BindingList 实现了 ICancelAddNew 接口,数据绑定机制使用该接口取消新添加的项(当您在 DataGridView 中添加一行后单击转义时,该行将消失)。

    我自己对 WPF 很陌生,不知道 ObservableCollection 提供的具体优势。

    希望这会有所帮助。

    【讨论】:

    • ObservableCollection 是线程安全的,我不知道 BindingList。
    • 这是不正确的。 Microsoft 的文档明确指出 ObservableCollection 不是线程安全的。 msdn.microsoft.com/en-us/library/ms668604.aspx
    • 第一个语句是错误的,因为 ObservableCollection 继承了 Collection 并且 Collection 确实实现了 ILIst 接口。
    • 此答案中的信息不正确。 ObservableCollection 确实实现了 IList.
    • 注意,ObservableCollection 也给出了实际删除的项目。有时这会很有帮助。 BindingList 不会告诉你删除了什么,只告诉你在哪里。
    【解决方案2】:

    我想你的答案就在那里:http://xceed.com/CS/blogs/dontpanic/archive/2009/04/01/i-notify-we-notify-we-all-wait-no-we-don-t.aspx

    简而言之,ObservableCollection 不会监听其子级的变化,而只会监听 Insert 和 Remove 事件。

    另一方面,BindingList 确实会监听其子级引发的更改和更新。但是因为绑定列表必须监听它所有的子节点来传播更改通知,这会导致更多的内存负载。

    希望这会有所帮助:)

    --布鲁诺

    【讨论】:

    • BindingList 监听集合中的每个项目(我猜是孩子?),因为如果集合中的项目发生更改,BindingList 会将该消息传递给网格或控件以更新单个单元格或值.这意味着整行不需要刷新其值。特定于 DataGridView,如果您在正在编辑的行上刷新一行而不是单个单元格,您的更改就会消失。这取决于您的需求。
    【解决方案3】:

    将我的两分钱添加到旧主题中:

    当将这些通用集合中的任何一个数据绑定到 WinForms DataGridView,然后更新源数据中多个选定行的属性时,您会看到:

    1. ObservableCollection<T> 只会更新最近选择的行的单元格值。
    2. BindingList<T> 将更新所有选定行的单元格值。

    我认为它们各有优缺点,但上面的例子对于那些不了解它的人来说可能是一个陷阱。

    【讨论】:

      猜你喜欢
      • 2011-09-09
      • 1970-01-01
      • 2010-09-19
      • 2017-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-28
      • 1970-01-01
      相关资源
      最近更新 更多