31

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

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

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

在后一种情况下,我可能不会使用 BindingSource,因为我可以收集到的数据表提供与 BindingSource 本身相同的功能。当添加、删除行等时,DataTable 将触发正确的事件,以便网格自动更新。

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

到目前为止听起来如何?我仍然觉得我的理解存在差距,这使我无法看到整个画面。到目前为止,这是一个相当模糊的问题,所以我会尝试提出一些更具体的问题——理想情况下,答案将参考上述示例或类似的东西......

(1) 在上述任何一个示例中都值得使用 BindingSource 吗?

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

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

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

4

3 回答 3

6

Pretty old question. Wonder why anyone hasn't answered it till now. OK, I'll try and share things from my experience.

A BindingSource is more than just a way to bind controls to collections. After having worked in WinForms for over a decade, the best features of a BindingSource that I like the most include:

  1. Binding (of course!)
  2. Currency management (I'll come to that in a second)
  3. A BindingSource can act as a data source of another BindingSource.

To fully appreciate these features, I'll explain them in the context of a DataSet, which is by far the most common type of data source used in WinForms, especially in line-of-business apps.

Currency management boils down the concept of current record. A DataTable is just a collection of DataRows, i.e. there is no concept of current record in DataTables. Same is the case of DataView (on a side note, you cannot directly bind to a DataTable; when you do that, it actually binds to the DefaultView property of that DataTable, which is a DataView. You could create your own DataView too).

Currency management really proves handy in case of Master/Detail kind of UI. So let's say you have a ListBox of Students in the left pane (Master), and several TextBoxes, ComboBoxes, CheckBoxes etc. in the right pane, with a grid of selected student's courses (Detail). In your DataSet, you have two DataTables named Student and Courses. For the sake of simplicity, I'm avoiding a gerund (Student_Course) here. The Course table has a foreign key StudentID. Here's how you setup binding here (note how all the 3 features I listed above are used in the setup below):

  1. Add two BindingSource controls to your form, named bsStudent and bsCourses.
  2. Set DataSource of bsStudent to Student DataTable.
  3. Set DataSource of bsCourses to bsStudent!
  4. In the DataMember property, you'll see the name of the relation that exists in the DataSet between our two tables. Select it!
  5. Set the binding of individual atomic controls to bsStudent's properties.
  6. Set the DataSource of courses grid bsCourses.

And you're done. Without writing a single line of code (so to speak), you have successfully created a master-details view. The BindingSource control will now take care of the current record in Students list and update not only the atomic controls (TextBoxes, ComboBoxes etc.), but also the courses grid, which will automatically update its contents to show the courses of currently selected student.

This, my friend, is the role of BindingSource (among other nice things like sorting, filtering etc.) which I like the most. Without involving a BindingSource in-between your controls and the data store, you'd not have the concept of current record and therefore would manually have to manage keeping all the UI in sync.

于 2015-03-30T06:05:15.853 回答
4

Hi I also have some confusion about the subject.
When I use datatables those implement all the interfaces.
However I always use the bindingsource just to be sure.. :)

There are some arguments why that I can think of

  1. Multiple views on the same recordset. (ie. 2 grids with diffent sort orders/filters)
  2. Filtering,Sorting while not changing the sort order of the records themselves (Filter/Sort)
  3. Ability to disable binding for a while for performance reasons. (when there are big updates in the table, don'y listen to all the IXXChanged events)
  4. IErrorprovider never worked for me without a bindingsource, however this could be my fault.
于 2010-06-15T05:47:25.190 回答
3

I also would like to add, using BindingSource, you can bind to a business object, which can implement INotifyPropertyChanged event, so if data is changed (whether by your code or someone else's code), your UI can automatically reflect the updates.

于 2011-09-23T19:52:56.280 回答