何时值得使用 BindingSource?

31

我认为我已经足够了解BindingSource类的作用 - 即在数据源和UI控件之间提供一个间接层。它实现了IBindingList接口,因此也支持排序。我已经经常使用它,没有太多问题。但我想知道我是否过度使用它。也许举个例子会有所帮助。

假设我在一个窗体上只有一个简单的文本框(使用WinForms),我想将该文本框绑定到一个返回字符串的简单类内部的属性上。在这种情况下,使用BindingSource是否值得呢?

现在假设我的表格上,我想将其绑定到一个DataTable。现在应该使用BindingSource吗?

对于后一种情况,我可能不会使用BindingSource,因为根据我所了解的,DataTable提供了BindingSource本身提供的相同功能。DataTable会在添加、删除等操作时触发正确的事件,使得表格自动更新。

但在第一种情况下,当文本字符串发生变化时,我可能会让包含该字符串属性的类实现INotifyPropertyChanged接口,以便在字符串更改时触发PropertyChanged事件。我将使用BindingSource,以便它可以监听这些PropertyChanged事件,从而在字符串更改时自动更新文本框。

到目前为止,这听起来怎么样?我仍然感觉有一些理解上的差距阻止我看到整个图景。迄今为止,这是一个相当模糊的问题,因此我将尝试提出一些更具体的问题 - 理想情况下,答案将参考上述示例或类似内容......

(1)在以上任何一个示例中使用BindingSource是否值得?

(2)开发人员似乎只是“假设”DataTable类会在正确的时间触发PropertyChanged事件。如何知道数据源是否能够实现这一点?是否有特定的接口应该实现,以便开发人员能够假定这种行为?

(3) 当考虑是否使用BindingSource时,被绑定的控件是否重要呢?或者只有数据源应该影响决策吗?也许答案是(这似乎很合理):控件需要足够智能地监听PropertyChanged事件,否则需要使用BindingSource。那么如何判断控件是否具备这样的功能呢?开发人员可以寻找特定的接口吗?

过去,正是由于这种困惑,我总是使用BindingSource。但我希望更好地了解什么时候使用它,以便仅在必要时这样做。


5
我认为这是一个很好的问题(相关问题列表),但某种原因未能得到一个合理的答案。 - HK1
3个回答

6

这是一个相对较旧的问题,奇怪为什么到现在没有人回答它。好吧,我会尝试从我的经验中分享一些东西。

BindingSource 不仅仅是将控件绑定到集合的一种方式。在 WinForms 上工作了十多年之后,我最喜欢 BindingSource 的最佳功能包括:

  1. 绑定(当然!)
  2. 货币管理(稍后会详细介绍)
  3. BindingSource 可以充当另一个 BindingSource数据源

为了充分理解这些功能,我将在 DataSet 的上下文中解释它们,这是迄今为止在 WinForms 中使用最广泛的数据源类型,特别是在商业应用程序中。

货币管理归结为当前记录的概念。 DataTable 只是一组 DataRow,即 DataTables 中没有当前记录的概念。 DataView 也是如此(顺便说一下,您不能直接绑定到 DataTable;当您这样做时,它实际上会绑定到该 DataTableDefaultView 属性,这是一个 DataView。您也可以创建自己的 DataView)。

在主 / 详细信息类型的 UI 中,货币管理确实非常方便。因此,假设您在左侧窗格(主控件)中有一个名为 “Students” 的 ListBox,以及右侧窗格中的多个 TextBoxes、ComboBoxes、CheckBoxes 等,并显示所选学生的课程网格(详细信息)。在您的 DataSet 中,有两个名为 StudentCourses 的 DataTable。为简单起见,我在这里避免了一种现在时态的名称(Student_Course)。Course 表具有外键 StudentID。下面是如何设置绑定(请注意以下设置中使用了我上面列出的所有3个功能):

  1. 向您的窗体添加两个 BindingSource 控件,分别命名为 bsStudentbsCourses
  2. bsStudentDataSource 设置为 Student DataTable。
  3. bsCoursesDataSource 设置为 bsStudent!
  4. DataMember 属性中,您将看到数据集中两个表之间存在的关系名称。选择它!
  5. 将各个原子控件的绑定设置为 bsStudent 的属性。
  6. 将课程网格 bsCourses 的数据源设置为 DataSource
并且你已经完成了。没有写一行代码(这么说),您已成功创建了主细节视图。BindingSource控件现在将负责学生列表中的当前记录,并更新不仅原子控件(文本框,组合框等),还包括课程网格,它将自动更新其内容以显示当前选择的学生的课程。
这就是BindingSource的作用(除了其他很好的东西,如排序、过滤等),我最喜欢的。如果在控件和数据存储之间不涉及BindingSource,则不会有当前记录的概念,因此必须手动管理所有UI的同步。

感谢@dotNET。所以,如果您查看我在问题中提到的两个(非常简单的)示例,这是否意味着您不会为它们使用BindingSource,因为不需要货币管理? - Justin
@Justin:在这两种情况下,都是可以的。BindingSource提供了一些其他功能,例如过滤和多重排序(对多列进行排序),这些功能可以通过BindingSource实现,或者您可以直接修改DataTable.DefaultView.RowFilterDataTable.DefaultView.Sort属性来实现相同的功能。 - dotNET

4

您好,关于这个主题我也有些困惑。
当我使用datatables时,它们会实现所有接口。
但是为了确保,我总是使用bindingsource.. :)

以下是我可以想到的一些理由:

  1. 在同一记录集上拥有多个视图。(例如:2个带有不同排序顺序/过滤条件的网格)
  2. 在不改变记录本身的排序顺序的情况下进行过滤和排序(Filter/Sort)
  3. 能够暂时禁用绑定以提高性能。(当表中有大量更新时,不要监听所有的IXXChanged事件)
  4. IErrorprovider如果没有Bindingsource,对我从来没有起作用,但这可能是我的错。

我希望有一个回答能够解释BindingSources在我的两个示例中的使用,但是已经过去了一周没有其他答案,所以我将选择这个作为被接受的答案。任何其他答案仍然欢迎... - Justin
3
第四个错误肯定是你的错 ;) IErrorProvider可以不用BindingSource使用,但你需要在你的模型上实现IDataErrorInfo接口。这里有一个描述:http://msdn.microsoft.com/en-us/library/41e17s4b.aspx ... 这是一篇写得非常好的文章。也许这是你的解决方案,Julian? - 70sCommander

3
我还想补充一点,使用 BindingSource,你可以绑定到一个实现了 INotifyPropertyChanged 事件的业务对象上,这样无论是你的代码还是其他人的代码修改了数据,你的用户界面都能自动反映更新。

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