BindingSource 组件体系结构

使用 BindingSource 组件,可以在各种情况下将所有 Windows 窗体控件绑定到数据源。

BindingSource 组件简化了将控件绑定到数据源的过程,与传统数据绑定相比,提供了以下优势:

  • 实现了对业务对象的设计时绑定。

  • 封装了 CurrencyManager 功能,并在设计时公开 CurrencyManager 事件。

  • 通过为本机不支持列表更改通知的数据源提供列表更改通知,简化了创建支持 IBindingList 接口的列表的过程。

  • IBindingList.AddNew 方法提供了扩展点。

  • 在数据源和控件之间提供了一个间接层。 当数据源可能在运行时发生更改时,这种间接性非常重要。

  • 与其他数据相关的 Windows 窗体控件(特别是 BindingNavigatorDataGridView 控件)互操作。

出于这些原因,BindingSource 组件是将 Windows 窗体控件绑定到数据源的首选方法。

BindingSource 功能

BindingSource 组件提供了一些功能,可以将控件绑定到数据。 借助这些功能,几乎无需编码即可实现大多数数据绑定方案。

BindingSource 组件通过提供一致的接口来访问许多不同类型的数据源来实现此目的。 这意味着要使用相同的过程绑定到任何类型。 例如,可以将 DataSource 属性附加到 DataSet 或业务对象,并且在这两种情况下都使用相同的属性、方法和事件集来操作数据源。

BindingSource 组件提供的一致接口极大地简化了将数据绑定到控件的过程。 对于提供更改通知的数据源类型,BindingSource 组件会自动在控件和数据源之间传达更改。 对于不提供更改通知的数据源类型,所提供的事件可以让你发出更改通知。 以下列表显示了 BindingSource 组件支持的功能:

间接寻址

BindingSource 组件在控件和数据源之间提供了一个间接层。 你无需将控件直接绑定到数据源,而是可以将该控件绑定到 BindingSource,并将数据源附加到 BindingSource 组件的 DataSource 属性。

通过这个间接层,不需要重置控件绑定即可更改数据源。 这为你提供了以下功能:

货币管理

BindingSource 组件实现了 ICurrencyManagerProvider 接口来为你处理货币管理。 使用 ICurrencyManagerProvider 接口,你也可以访问 BindingSource 的货币管理器,此外还可以访问绑定到同一个 DataMember 的另一个 BindingSource 的货币管理器。

BindingSource 组件封装 CurrencyManager 功能并公开最常见的 CurrencyManager 属性和事件。 下表描述了与货币管理相关的一些成员。

CurrencyManager 属性
获取与 BindingSource 关联的货币管理器。

GetRelatedCurrencyManager 方法
如果有另一个 BindingSource 绑定到指定的数据成员,则获取其货币管理器。

Current 属性
获取数据源的当前项。

Position 属性
获取或设置基础列表中的当前位置。

EndEdit 方法
将挂起的更改应用于基础数据源。

CancelEdit 方法
取消当前的编辑操作。

列表形式的数据源

BindingSource 组件实现了 IBindingListViewITypedList 接口。 通过此实现,可以将 BindingSource 组件本身用作数据源,无需任何外部存储。

BindingSource 组件附加到数据源时,它会将数据源公开为列表。

可以将 DataSource 属性设置为多个数据源。 其中包括类型、对象和类型列表。 生成的数据源将以列表的形式公开。 下表显示了一些常见数据源和生成的列表评估。

数据源属性 列表结果
空引用(在 Visual Basic 中为 Nothing 对象的空 IBindingList。 添加项会将列表设置为所添加项的类型。
空引用(在 Visual Basic 中为 Nothing)和 DataMember 不支持;会引发 ArgumentException
非列表类型或类型“T”的对象 类型“T”的空 IBindingList
数组实例 包含数组元素的 IBindingList
IEnumerable 实例 包含 IEnumerable 项的 IBindingList
包含类型“T”的列表实例 包含类型“T”的 IBindingList 实例。

此外,还可以将 DataSource 设置为其他列表类型,例如 IListSourceITypedList,并且 BindingSource 将相应地处理它们。 在这种情况下,列表中包含的类型应具有无参数构造函数。

IBindingList 形式的 BindingSource

BindingSource 组件提供了用于以 IBindingList 的形式访问和操作基础数据的成员。 下表描述了其中的一些成员。

成员 说明
List 属性 获取从 DataSourceDataMember 属性的计算结果得出的列表。
AddNew 方法 在基础列表中添加一个新项。 适用于实现 IBindingList 接口并允许添加项(即,AllowNew 属性设置为 true)的数据源。

创建自定义项

可以处理 AddingNew 事件以提供自己的项创建逻辑。 在将新对象添加到 BindingSource 之前,AddingNew 事件就发生了。 在调用 AddNew 方法之后,但在将新项添加到基础列表之前,会引发此事件。 通过处理此事件,可以提供自定义项创建行为,无需从 BindingSource 类派生。 有关详细信息,请参阅如何:使用 Windows 窗体 BindingSource 自定义项添加

创建事务项

BindingSource 组件实现了 ICancelAddNew 接口,该接口支持事务项创建。 使用对 AddNew 的调用临时创建新项后,可以通过以下方式提交或回滚添加:

  • EndNew 方法将显式提交挂起的添加。

  • 执行另一个收集操作(如插入、删除或移动)将隐式提交挂起的添加。

  • 如果尚未提交 CancelNew 方法,该方法将回滚挂起的添加。

IEnumerable 支持

BindingSource 组件允许将控件绑定到 IEnumerable 数据源。 使用此组件,可以绑定到数据源,例如 System.Data.SqlClient.SqlDataReader

IEnumerable 数据源分配给 BindingSource 组件时,BindingSource 会创建一个 IBindingList,并将 IEnumerable 数据源的内容添加到列表中。

设计时支持

某些对象类型无法在设计时创建,例如从工厂类创建的对象,或者由 Web 服务返回的对象。 有时,你可能必须在设计时将控件绑定到这些类型,即使内存中没有控件可以绑定到的对象。 例如,你可能需要使用自定义类型的公共属性的名称来标记 DataGridView 控件的列标题。

为了支持此场景,BindingSource 组件支持绑定到 Type。 将 Type 分配给 DataSource 属性时,BindingSource 组件将创建 Type 项的一个空 BindingList<T>。 你随后绑定到 BindingSource 组件的任何控件都会在设计时或运行时收到你的类型的属性或架构存在的提醒。 有关详细信息,请参阅如何:将 Windows 窗体控件绑定到类型

静态 ListBindingHelper 方法

System.Windows.Forms.BindingContextSystem.Windows.Forms.CurrencyManagerBindingSource 类型都共享从 DataSource/DataMember 对生成列表的通用逻辑。 此外,这个通用逻辑被公开,供控件作者和其他第三方在以下 static 方法中使用:

使用 IBindingListView 接口进行排序和筛选

BindingSource 组件实现了 IBindingListView 接口,这将扩展 IBindingList 接口。 IBindingList 提供单列排序,IBindingListView 提供高级排序和筛选。 使用 IBindingListView,如果数据源同时还实现了其中一个接口,你就可以对数据源中的项进行排序和筛选。 BindingSource 组件不提供这些成员的引用实现。 相反,调用被转发到基础列表。

下表描述了用于排序和筛选的属性。

成员 说明
Filter 属性 如果数据源是 IBindingListView,则获取或设置用于筛选已查看的行的表达式。
Sort 属性 如果数据源是 IBindingList,则获取或设置用于排序的列名称并对顺序信息进行排序。

- 或者 -

如果数据源是 IBindingListView 并支持高级排序,则获取用于排序的多个列名称以及排序顺序

与 BindingNavigator 集成

可以使用 BindingSource 组件将任何 Windows 窗体控件绑定到数据源,但 BindingNavigator 控件是专为用于 BindingSource 组件而设计的。 BindingNavigator 控件提供了用户界面来控制 BindingSource 组件的当前项。 默认情况下,BindingNavigator 控件提供与 BindingSource 组件上的导航方法对应的按钮。 有关详细信息,请参阅如何:使用 Windows 窗体 BindingNavigator 控件导航数据

另请参阅