Data binding has been greatly improved in .Net 2.0. It is now very easy to bind to any type of object or collection of objects and get a great design-time experience plus a pretty good run-time experience. However, to fully realize the potential for binding in .Net 2.0 you need to be aware of all of the classes, interfaces, and attributes that collaborate to provide the rich interactions available.
This post is not intended to be a tutorial. It is simply a list of the classes and interfaces that you should be aware of when building a data bound application. If you are looking for a good book on this subject, I would recommend Data Binding with Windows Forms 2.0 by Brian Noyes.
These classes allow you to bind your data source to the controls on a form.
The BindingSource class handles all of the interactions between the controls and the actual instance of the data source. It is the primary class used in data binding. A BindingSource is automatically created when you bind a control to a data source.
This class can adapt to many different types of data sources from the very simple (example, a basic class that exposes public properties) to the very complex (example, a collection of objects that have custom properties that can change dynamically during the life of the object). The interfaces that this class can collaborate with are discussed in the Data Source Interfaces section.
The Binding class associates a property on a control to a property on a data source and also associates it with a BindingSource instance to handle the actual interaction between the control and the data source.
This class exposes events for converting values from one data type to another. So, if you have special formatting/parsing logic, you might need to hook up to these events. If you have a custom class that can be converted to/from a string, you can also implement the IFormattable interface along with a public static <MyObject> Parse(<string>) method, implement the IConvertible interface, or associate the class with a TypeConverter (there are many formatting/parsing options). The TypeConverter might be the best option because of the additional support it provides for conversions, however, it is also the most complex. Implementing the IConvertible interface is the second best option and it allows your class to be converted using the System.Convert class.
|Collaborates With: BindingSource, BindingManagerBase, IBindableComponent, IFormatProvider, IFormattable, TypeConverter, IConvertible|
Data Source Interfaces
Implement these interfaces on your custom data source to provide the features required for binding. As a note, you can replicate the behavior of binding to a DataSet by implementing these interfaces (this is how the DataSet, DataTable, DataView, DataRow, and DataRowView classes bind to controls).
The IBindingList interface provides many of the properties and methods that the BindingSource needs to provide the rich interaction that most people expect from data binding. This interface allows data items to be added and removed as well as providing notification when a data item is removed, added, or modified).
The BindingList<T> class implements this interface and allows this interface to be used without having to write a lot of code.
|The IListSource interface allows a bound data item to provide a list without implementing the IList interface directly. It can also provide a list of lists if the ContainsListCollection property returns true.|
The ITypedList interface allows a list to provide information about the properties that are available for the data items that it contains. This interface is used by the Visual Studio designer to determine the properties that are available for binding.
The GetItemProperties method on this interface can be used to get the properties for related data items or lists by passing in the property descriptors that define the relationship. The GetListName method is not really used by the .Net FX. It was used by the old data grid in version 1.1 to display the names of the child lists while navigating the grid
The IBindingListView interface adds support for advanced filtering and sorting to the IBindingList interface.
The ICancelAddNew interface is implemented by a collection class and allows new data items to exist in a transient state (it’s not yet added to the collection, but will be once the user has completed editing it). This can be used in conjunction with the IEditableObject interface which is implemented by the data item.
|Collaborates With: IEditableObject|
The INotifyPropertyChanged interface allows a data item to notify a container (such as a list) that a property has changed.
|Collaborates With: BindingList<T>|
The IEditableObject interface allows a data item to participate in a transaction. You begin the transaction by calling BeginEdit and end it by calling EndEdit or CancelEdit. CancelEdit reverts the record to the state when BeginEdit was called.
|Collaborates With: ICancelAddNew|
The IDataErrorInfo interface allows a data item to provide error details to the user. If the data is bound to a DataGridView or there is a ErrorProvider component for the form, an icon is displayed next to the control that is bound to the field and the error is displayed as a tooltip when the user places the mouse over the icon.
|Collaborates With: ErrorProvider|
The ICustomTypeDescriptor interface allows a data item to provide a custom set of properties. This is very useful if your data item does not use properties of the class to expose the data (for example, DataRow does not have properties for the data, you have to send in the name of a column to get the data).
The BindingList<T> class calls into this interface when it's properties are called.
|Collaborates With: BindingList<T>, BindingSource|
Bound Component Interfaces and Attributes
These interfaces and attributes allow you to provide a custom bound component or control.
The IBindableComponent interface provides the basic properties needed to hook up binding to a component or control.
Control implements this interface.
The ISupportInitialize interface allows interdependent properties to be set on a component in arbitrary order. This is used primarily for WinForm components added to the designer.
Collaborates With: Visual Studio Designer
The ISupportInitializeNotification interface allows components to be notified of initialization of other components. This is useful if the initialization of one component requires another component to be initialized first.
The DefaultBindingPropertyAttribute identifies the property on the component that should be used as the default binding property. Should match the data type for the property it is being bound to through the data member.
The ComplexBindingPropertiesAttribute tells the VS designer which properties contain the data source and data member for complex data binding.