ObservableCollection(Of T)和BindingList(Of T)有何不同?

24

我在过去两年中开发了一些基于数据的Winforms应用程序,所有工作都很顺利。这些应用程序是基于层构建的(DataAccess、Business Logic和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迁移到WPF的UI层。

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

3个回答

16

BindingList会监听集合中的每个项(它们的子项,我猜?),因为如果集合中的某个项发生更改,BindingList会将该消息传递给网格或控件以更新单个单元格或值。这意味着不需要刷新整行的值。特别针对DataGridView,如果您刷新了一行而不是单个单元格,则在您正在编辑的行上,您所做的更改将消失。这取决于您的需求。 - TamusJRoyce

11

Claber,

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

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

我自己对WPF非常陌生,不知道ObservableCollection提供了哪些特定的优势。

希望这可以帮到你。


ObservableCollection 是线程安全的,至于 BindingList 我不确定。 - Shimmy Weitzhandler
10
这不正确。微软的文档明确指出ObservableCollection不是线程安全的。http://msdn.microsoft.com/en-us/library/ms668604.aspx - kevindaub
12
第一个声明是错误的,因为ObservableCollection<T>继承自Collection<T>,而Collection<T>确实实现了ILIst<T>接口。 - Roman Zavalov
1
这个答案中的信息不正确。ObservableCollection<T>确实实现了IList<T>。 - jnm2
1
注意,ObservableCollection<T> 还会提供实际删除的项。有时这非常有帮助。BindingList<T> 不会告诉你删除了什么,只会告诉你在哪里。 - jnm2

3

以下是我对旧话题的补充:

当将这两个通用集合绑定到WinForms DataGridView并更新多个选定行的源数据属性时,您会看到:

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

我认为它们各有优缺点,但上述示例可能会让那些不知情的人感到困惑。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接