什么时候值得使用BindingSource?

时间:2010-06-15 04:17:52

标签: .net winforms data-binding bindingsource

我认为我很清楚BindingSource类的功能 - 即在数据源和UI控件之间提供一个间接层。它实现了IBindingList接口,因此也提供了对排序的支持。而且我经常使用它,没有太多问题。但我想知道我是否经常使用它而不是我应该使用它。也许一个例子会有所帮助。

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

现在让我说我的表单上有一个网格,我想将它绑定到DataTable。我现在应该使用BindingSource吗?

在后一种情况下,我可能使用BindingSource,作为DataTable,从我可以收集的内容,提供与BindingSource本身相同的功能。添加,删除行等时,DataTable将触发正确的事件,以便网格自动更新。

但是在第一个将文本框绑定到字符串的情况下,我可能会让包含字符串属性的类实现INotifyPropertyChanged,这样它就可以在字符串更改时触发PropertyChanged事件。我会使用BindingSource,以便它可以监听这些PropertyChanged事件,以便它可以在字符串更改时自动更新文本框。

到目前为止这听起来怎么样?我仍然觉得我的理解存在差距,这使我无法看到整体情况。到目前为止,这是一个非常模糊的问题,所以我会尝试提出一些更具体的问题 - 理想情况下,答案会引用上面的例子或类似的东西......

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

(2)似乎开发人员只是“假设”DataTable类在正确的时间触发PropertyChanged事件时会做正确的事情。如何知道数据源是否能够执行此操作?是否存在数据源应该实现的特定接口,以便开发人员能够承担此行为?

(3)在考虑是否使用BindingSource时,Control绑定的是否重要?或者只是影响决策的数据源?也许答案是(这看起来足够合乎逻辑):Control需要足够智能以监听PropertyChanged事件,否则需要BindingSource。那么如何判断Control是否能够做到这一点呢?同样,开发人员可以查找控件必须实现的特定接口吗?

正是这种困惑在过去导致我总是使用BindingSource。但是我想更好地理解何时使用它,所以我只在必要时这样做。

3 个答案:

答案 0 :(得分:4)

嗨我对这个问题也有一些困惑 当我使用数据表时,那些实现所有接口 但是我总是使用bindingsource来确保.. :)

有一些争论为什么我能想到

  1. 同一记录集上的多个视图。 (即具有不同排序顺序/过滤器的2个网格)
  2. 过滤,排序而不更改记录本身的排序顺序(过滤/排序)
  3. 出于性能原因,暂时禁用绑定的能力。 (当表中有大的更新时,不要听所有的IXXChanged事件)
  4. IErrorprovider在没有绑定源的情况下从未为我工作过,但这可能是我的错。

答案 1 :(得分:4)

很老的问题。不知道为什么有人直到现在都没有回答。好的,我会尝试从我的经验中分享一些东西。

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

  1. 绑定(当然!)
  2. 货币管理(我将在一秒钟内完成)
  3. BindingSource可以充当另一个BindingSource数据源
  4. 为了完全理解这些功能,我将在DataSet的上下文中解释它们,这是迄今为止WinForms中使用的最常见的数据源类型,尤其是在业务线应用程序中。

    货币管理归结为当前记录的概念。 DataTable只是DataRow的集合,即DataTables中没有当前记录的概念。同样是DataView的情况(在旁注中,您不能直接绑定到DataTable;当您这样做时,它实际上绑定到DefaultView的{​​{1}}属性},这是DataTable。您也可以创建自己的DataView

    对于Master / Detail类型的UI,货币管理确实很方便。因此,让我们假设您在左侧窗格(Master)中有DataView个学生,在右侧窗格中有几个TextBoxes,ComboBoxes,CheckBoxes等,其中包含选定学生课程的网格(详情)。在DataSet中,您有两个名为ListBoxStudent的DataTable。为了简单起见,我在这里避免使用动名词(Student_Course)。 Courses表有一个外键Course。以下是您在此处设置绑定的方法(请注意我在上面的设置中使用了上面列出的所有3个功能):

    1. 向表单添加两个StudentID控件,名为BindingSourcebsStudent
    2. bsCourses的{​​{1}}设置为DataSource DataTable。
    3. bsStudent的{​​{1}}设置为bsStudent!
    4. Student属性中,您将看到两个表之间DataSet中存在的关系的名称。选择它!
    5. 将各个原子控件的绑定设置为DataSource的属性。
    6. 设置bsCourses课程grid bsCourses。
    7. 你已经完成了。无需编写单行代码(可以这么说),您已成功创建了主 - 详细信息视图。 BindingSource控件现在将处理学生列表中的当前记录,不仅更新原子控件(TextBoxes,ComboBoxes等),还更新课程网格,它将自动更新其内容以显示当前入选学生的课程。

      我的朋友,这是BindingSource的作用(除了排序,过滤等其他很好的东西),我最喜欢它。如果您的控件和数据存储之间没有DataMember,则您不具备当前记录的概念,因此需要手动管理以保持所有UI同步。

答案 2 :(得分:3)

我还想添加,使用BindingSource,您可以绑定到一个业务对象,它可以实现INotifyPropertyChanged事件,因此如果数据被更改(无论是通过您的代码还是其他人的代码),您的UI可以自动反映更新。