与数据绑定相关的接口
使用 ADO.NET,可以创建许多不同的数据结构,以满足应用程序和正在处理的数据的绑定需要。 你可能希望创建自己的类,以便在 Windows 窗体中提供或使用数据。 这些对象可以提供各种级别的功能和复杂性,从基本的数据绑定,到提供设计时支持、错误检查、更改通知,甚至是支持对数据本身所做更改的结构化回退。
数据绑定接口的使用者
以下部分描述两组接口对象。 第一组列出数据源作者在数据源上实现的接口。 这些接口旨在由数据源使用者使用,在多数情况下,这些使用者是 Windows 窗体控件或组件。 第二组列出面向组件作者设计的接口。 组件作者在创建支持数据绑定的组件时使用这些接口,以便它们能够被 Windows 窗体数据绑定引擎使用。 可以在与窗体关联的类中实现这些接口以启用数据绑定;每种情况都表示一个类,该类所实现的接口支持与数据进行交互。 Visual Studio 快速应用程序开发 (RAD) 数据设计体验工具已经利用了该功能。
要由数据源作者实现的接口
下列接口设计为由 Windows 窗体控件使用:
IList 接口
实现 IList 接口的类可以是 Array、ArrayList 或 CollectionBase。 这些是 Object 类型的项的索引列表。 这些列表必须包含同源类型,因为索引中的第一项确定类型。 IList 仅在运行时可用于绑定。
注意
如果希望创建要与 Windows 窗体绑定的业务对象列表,则应当考虑使用 BindingList<T>。 BindingList<T> 是可扩展的类,用于实现双向 Windows 窗体数据绑定所需的主要接口。
IBindingList 接口
实现 IBindingList 接口的类提供一种更高级别的数据绑定功能。 此实现在列表项更改时(例如,客户列表中的第三项更改了 Address 字段)和列表本身更改时(例如,列表中项的数量增加或减少)都提供基本的排序功能和更改通知。 如果计划将多个控件绑定到同一个数据,但是希望将在其中某个控件中进行的数据更改传播到其他绑定控件,更改通知就非常重要。
注意
更改通知是通过 SupportsChangeNotification 属性为 IBindingList 接口启用的,当该属性为
true
时,会引发一个 ListChanged 事件,指示列表或列表中的项已发生更改。更改的类型由 ListChangedEventArgs 参数的 ListChangedType 属性来描述。 因此,当数据模型进行更新时,任何依赖视图(例如,绑定到同一个数据源的其他控件)也会进行更新。 但是,包含在列表中的对象在更改时必须通知该列表,以便该列表引发 ListChanged 事件。
注意
BindingList<T> 提供 IBindingList 接口的泛型实现。
-
实现 IBindingListView 接口的类提供 IBindingList 实现的所有功能以及筛选和高级排序功能。 此实现使用属性描述符-方向对提供基于字符串的筛选和多列排序能力。
-
实现 IEditableObject 接口的类允许对象控制对该对象进行的更改何时成为永久更改。 此实现提供 BeginEdit、EndEdit 和 CancelEdit 方法,这些方法允许回滚对对象进行的更改。 下面简述了 BeginEdit、EndEdit 和 CancelEdit 方法的功能,以及它们如何搭配使用,以支持对数据更改进行可能的回滚:
BeginEdit 方法发出开始对一个对象进行编辑的信号。 实现此接口的对象需要存储 BeginEdit 方法调用后的任何更新,这样,如果调用 CancelEdit 方法,就可以放弃这些更新。 在数据绑定 Windows 窗体中,可以在单个编辑事务的范围内多次调用 BeginEdit(例如,BeginEdit、BeginEdit 和 EndEdit)。 IEditableObject 的实现应当跟踪 BeginEdit 是否已被调用,并忽略对 BeginEdit 的后续调用。 因为可多次调用此方法,所以对它的后续调用应是非破坏性的,这一点很重要;即,对 BeginEdit 的后续调用不能损坏已进行的更新或更改在第一次调用 BeginEdit 时保存的数据。
CancelEdit 方法放弃对对象所做的任何更改。
有关 BeginEdit、EndEdit 和 CancelEdit 方法的工作原理的详细信息,请参阅将数据保存回数据库。
DataGridView 控件使用数据功能的这种事务性概念。
-
实现 ICancelAddNew 接口的类通常实现 IBindingList 接口,并允许回滚用 AddNew 方法向数据源添加的数据。 如果数据源实现 IBindingList 接口,则还应当让其实现 ICancelAddNew 接口。
-
实现 IDataErrorInfo 接口的类允许对象向绑定控件提供自定义错误信息:
IEnumerable 接口
实现 IEnumerable 接口的类通常由 ASP.NET 使用。 只能通过 BindingSource 组件来使用 Windows 窗体对此接口的支持。
注意
BindingSource 组件将所有的 IEnumerable 项复制到一个单独的列表中以实现绑定。
ITypedList 接口
实现 ITypedList 接口的集合类提供如下功能:控制向绑定控件公开的属性集以及这些属性的顺序。
注意
在实现 GetItemProperties 方法时,如果 PropertyDescriptor 数组不为 null,则该数组中的最后一项为属性描述符,它描述作为另一个项列表的列表属性。
-
实现 ICustomTypeDescriptor 接口的类提供有关其自身的动态信息。 此接口与 ITypedList 类似,但是它用于对象,而非列表。 此接口由 DataRowView 用来设计基础行的架构。 CustomTypeDescriptor 类提供 ICustomTypeDescriptor 的简单实现。
注意
若要支持到实现 ICustomTypeDescriptor 的类型的设计时绑定,该类型还必须实现 IComponent 并且作为实例存在于窗体上。
IListSource 接口
实现 IListSource 接口的类在非列表对象上启用基于列表的绑定。 IListSource 的 GetList 方法用于从某个对象返回一个不是从 IList 继承的可绑定列表。 IListSource 由 DataSet 类使用。
-
实现 IRaiseItemChangedEvents 接口的类是可绑定的列表,该列表还实现 IBindingList 接口。 此接口用于指示类型是否通过其 RaisesItemChangedEvents 属性引发 ItemChanged 类型的 ListChanged 事件。
注意
如果数据源提供用来列出前面描述的事件转换的属性,并且与 BindingSource 组件进行交互,则应当实现 IRaiseItemChangedEvents。 否则,BindingSource 还会执行用来列出事件转换的属性,这将导致性能下降。
-
实现 ISupportInitialize 接口的组件利用批处理优化来设置属性并初始化共存属性。 ISupportInitialize 包含两种方法:
ISupportInitializeNotification 接口
实现 ISupportInitializeNotification 接口的组件还实现 ISupportInitialize 接口。 使用此接口,可以通知其他 ISupportInitialize 组件初始化已完成。 ISupportInitializeNotification 接口包含两个成员:
IsInitialized 返回一个
boolean
值,该值指示组件是否已初始化。Initialized 在调用 EndInit 时发生。
-
实现此接口的类是一个在其任何属性值更改时都会引发事件的类型。 此接口旨在替换控件的每个属性都有一个更改事件这种模式。 用在 BindingList<T> 中时,业务对象应当实现 INotifyPropertyChanged 接口,BindingList`1 会将 PropertyChanged 事件转换为 ItemChanged 类型的 ListChanged 事件。
注意
对于在绑定客户端和数据源之间的绑定中发生的更改通知,要么应当让绑定数据源类型实现 INotifyPropertyChanged 接口(首选方法),要么为绑定类型提供 propertyName
Changed
事件,但是不应同时选择这两种方法。
要由组件作者实现的接口
下列接口设计为由 Windows 窗体数据绑定引擎使用:
-
实现此接口的类是支持数据绑定的非控件组件。 此类通过该接口的 DataBindings 和 BindingContext 属性返回组件的数据绑定和绑定上下文。
注意
如果组件从 Control 继承,则无需实现 IBindableComponent 接口。
-
实现 ICurrencyManagerProvider 接口的类是一个组件,该组件提供其自己的 CurrencyManager,用来管理与此特定组件关联的绑定。 对自定义 CurrencyManager 的访问是通过 CurrencyManager 属性提供的。
注意
从 Control 继承的类通过它的 BindingContext 属性自动管理绑定,因此,需要实现 ICurrencyManagerProvider 的情况相当罕见。