什么时候值得使用 BindingSource?
Posted
技术标签:
【中文标题】什么时候值得使用 BindingSource?【英文标题】:When is it worth using a BindingSource? 【发布时间】:2011-03-03 19:37:05 【问题描述】:我想我对 BindingSource 类的作用非常了解 - 即在数据源和 UI 控件之间提供一个间接层。它实现了 IBindingList 接口,因此还提供了对排序的支持。而且我已经使用它足够频繁,没有太多问题。但我想知道我是否经常使用它。也许举个例子会有所帮助。
假设我在表单上只有一个简单的文本框(使用 WinForms),我想将该文本框绑定到返回字符串的类中的一个简单属性。在这种情况下是否值得使用 BindingSource?
现在假设我的表单上有一个网格,我想将它绑定到一个 DataTable。我现在应该使用 BindingSource 吗?
在后一种情况下,我可能不使用 BindingSource,因为据我所知,DataTable 提供了与 BindingSource 本身相同的功能。当添加、删除行等时,DataTable 将触发正确的事件,以便网格自动更新。
但在文本框绑定到字符串的第一种情况下,我可能会让包含字符串属性的类实现 INotifyPropertyChanged,以便在字符串更改时触发 PropertyChanged 事件。我会使用 BindingSource 以便它可以侦听这些 PropertyChanged 事件,以便在字符串更改时自动更新文本框。
到目前为止,这听起来如何?我仍然觉得我的理解存在差距,这使我无法看到整个画面。到目前为止,这是一个相当模糊的问题,所以我会尝试提出一些更具体的问题——理想情况下,答案将参考上述示例或类似的内容......
(1) 在上述任一示例中是否值得使用 BindingSource?
(2) 开发人员似乎只是“假设”DataTable 类会做正确的事情,在正确的时间触发 PropertyChanged 事件。如何知道数据源是否能够做到这一点?是否存在数据源应实现的特定接口,以便开发人员能够承担这种行为?
(3) 在考虑是否使用 BindingSource 时,绑定什么 Control 是否重要?还是只有数据源会影响决策?也许答案是(这似乎很合乎逻辑):控件需要足够智能以侦听 PropertyChanged 事件,否则需要 BindingSource。那么如何判断 Control 是否有能力做到这一点呢?同样,是否有开发人员可以寻找的特定接口,控件必须实现?
在过去,正是这种困惑导致我总是使用 BindingSource。但我想更准确地了解何时使用它,以便仅在必要时才这样做。
【问题讨论】:
我认为这是一个很好的问题(相关问题列表),但不知何故未能真正得到体面的答案。 【参考方案1】:相当老的问题。奇怪为什么到现在还没有人回答。好的,我会尝试分享我的经验。
BindingSource
不仅仅是一种将控件绑定到集合的方法。在 WinForms 工作了十多年后,我最喜欢 BindingSource
的最佳功能包括:
-
绑定(当然!)
货币管理(我稍后会谈到)
BindingSource
可以充当另一个BindingSource
的数据源。
为了充分了解这些功能,我将在 DataSet 的上下文中对其进行解释,这是迄今为止 WinForms 中使用的最常见的数据源类型,尤其是在业务线应用程序中。
货币管理归结为当前记录的概念。 DataTable
只是 DataRow
s 的集合,即 DataTables 中没有 current 记录的概念。 DataView
的情况也是如此(附带说明,您不能直接绑定到 DataTable
;当您这样做时,它实际上绑定到 DataTable
的 DefaultView
属性,即 DataView
. 你也可以创建自己的DataView
)。
在主/明细类 UI 的情况下,货币管理确实很方便。因此,假设您在左窗格(Master)中有一个 ListBox
的学生,在右窗格中有几个 TextBoxes、ComboBoxes、CheckBoxes 等,并带有一个选定学生课程的网格(详细信息)。在您的数据集中,您有两个名为Student
和Courses
的数据表。为了简单起见,我在这里避免使用动名词(Student_Course)。 Course
表有一个外键 StudentID
。这是您在此处设置绑定的方式(请注意我上面列出的所有 3 个功能在下面的设置中是如何使用的):
-
将两个
BindingSource
控件添加到您的表单中,分别命名为bsStudent
和bsCourses
。
将bsStudent
中的DataSource
设置为Student
DataTable。
将DataSource
的bsCourses
设置为bsStudent!
在DataMember
属性中,您将看到我们两个表之间存在于DataSet 中的关系的名称。选择它!
将各个原子控件的绑定设置为bsStudent
的属性。
设置课程网格 bsCourses 的 DataSource
。
你就完成了。无需编写任何代码(可以这么说),您就成功地创建了主从视图。 BindingSource 控件现在将处理学生列表中的 current 记录,不仅更新原子控件(文本框、组合框等),还更新课程网格,这将自动更新其内容以显示当前所选学生的课程。
我的朋友,这就是我最喜欢的 BindingSource 的角色(以及其他不错的功能,如排序、过滤等)。如果在控件和数据存储之间不涉及BindingSource
,您将没有当前记录的概念,因此必须手动管理保持所有 UI 同步。
【讨论】:
感谢@dotNET。因此,如果您查看我在问题中提到的两个(非常简单的)示例,这是否意味着您不会对其中任何一个使用 BindingSource,因为不需要货币管理? @Justin:在这两种情况下,都是的。BindingSource
提供了一些其他功能,例如过滤和多列排序(在多个列上排序),可以通过 BindingSource
来实现,也可以直接修改 DataTable.DefaultView.RowFilter
和 DataTable.DefaultView.Sort
属性来实现。
【参考方案2】:
您好,我也对这个主题有些困惑。 当我使用数据表时,它们实现了所有接口。 但是,我总是使用 bindingsource 来确定.. :) 有一些论据为什么我能想到
-
同一记录集上的多个视图。 (即 2 个具有不同排序顺序/过滤器的网格)
过滤、排序而不改变记录本身的排序顺序(过滤/排序)
出于性能原因暂时禁用绑定的能力。 (当表中有大的更新时,不要听所有的 IXXChanged 事件)
IErrorprovider 在没有绑定源的情况下无法为我工作,但这可能是我的错。
【讨论】:
我希望得到一个解释 BindingSources 的使用的答案,因为它们与我的两个示例相关,但由于已经一周没有任何其他答案,我将选择它作为接受的答案。不过,仍然欢迎任何其他答案... 第 4 次肯定是你的错;) IErrorProvider 可以在没有 BindingSource 的情况下工作,但是你必须在你的模型上实现 IDataErrorInfo。此处描述:msdn.microsoft.com/en-us/library/41e17s4b.aspx ... 一篇写得很好的文章。也许你的解决方案朱利安?【参考方案3】:我还想补充一点,使用 BindingSource,您可以绑定到业务对象,该对象可以实现 INotifyPropertyChanged 事件,因此如果数据发生更改(无论是您的代码还是其他人的代码),您的 UI 可以自动反映更新.
【讨论】:
以上是关于什么时候值得使用 BindingSource?的主要内容,如果未能解决你的问题,请参考以下文章
Form DataGridView绑定BindingSource的几种方式