One of the most powerful aspects of .NET and Windows Forms is data binding. Historically, data binding was used to bind views to data stored in databases. Some database management systems, such as Microsoft Access, have provided GUI APIs to help developers quickly bind to data.
This sample is taken from Chapter 6: "Windows Forms Data Binding" of the Blue Vision Title "Developing .NET Custom Controls and Designers using C#"
Data Binding Interfaces
.NET provides a standard set of interfaces
related to data binding. Each of these interfaces is described below.
IList
Any class that implements IList must support a list of homogenous types. That is, all
list items must be of the same type. The first item in the list always determines
the type. Some of the base classes that implement IList include Array, ArrayList,
CollectionBase, DataView, and DataViewManager.
Typed IList
Similar to IList,
the list must be of homogenous types. However, classes of this type can only
be data bound at runtime.
IList and IComponent
When a class implements both IList and IComponent, the class
can be data bound at design time. When dragging the component from the toolbox
to a form, you will notice that the component appears in the component tray,
like a DataSet and DataAdapter.
IListSource
This interface allows an object to "act" like a list for data binding
purposes. The implemented object is not an instance of IList, but it should
be able to provide one. The DataSet and DataTable objects both implement this
interface. IListSource provides a single property and a single method which
are described below:
ContainsListCollection: Indicates whether the collection is a collection
of IList objects. For the DataSet implementation, this property returns true,
because the DataSet contains a collection of collections. For the DataTable
implementation, this property returns false, because the DataTable contains
a collection of objects. In simple terms, implement this property to indicate
how deep to go for returning a bindable list.
GetList: Returns the IList that will be data-bound. The DataSet
uses this property to return a DataViewManager. The DataTable uses this property
to return a DataView.
ITypedList
This interface allows an object to expose its items' properties. This interface
is useful in situations where the public properties of the object should be
different than the properties available for data binding. This interface is
also necessary during complex binding when a list is empty but you still need
to know the properties of the list item. (Remember, IList alone uses the data
type of the first item in the list.) This is useful when columns headers should
be created for empty lists.
IBindingList
This interface offers change notification when the list and list items have changed. There is one
property, SupportsChangeNotification, which determines
whether this interfaces ListChanged event will
be raised. The ListChangedEventArgs contains a ListChangedType property for describing the type of change
that occurred. The available ListChangedType values
are as follows:
ItemAdded: An item has been added to the list. The index of the
new item is the value of ListChangedEventArgs.NewIndex.
ItemChanged: An item in the list has been changed. The index of
the changed item is the value of ListChangedEventArgs.NewIndex
ItemDeleted: An item has been removed from the list. The index of
the deleted item is the value of ListChangedEventArgs.NewIndex.
ItemMoved: An item has been moved to another location within the
list. The previous index is the value of ListChangedEv.entArgs.OldIndex. The
new index is the value of ListChangedEventArgs.NewIndex.
PropertyDescriptorAdded: A PropertyDescriptor has been added.
PropertyDescriptorChanged: A PropertyDescriptor has been changed.
PropertyDescriptorDeleted: A PropertyDescriptor has been deleted.
Reset: The list has a lot of changes and controls should refresh
themselves.
IEditableObject
This interface supports transaction-like
operations. It allows objects to specify when changes should be made permanent.
Hence, it allows changes to be rolled back. The DataGrid
is one control that opts to call methods of this interface. The following
methods are defined in this interface:
BeginEdit: Signals that an edit operation has started. Any changes
to the object should be temporarily stored after this method has been called.
When implementing this method, be sure that back-to-back calls are non-destructive.
That is, the method itself should not create any changes to any temporary
objects.
CancelEdit: Cancels any changes made after the BeginEdit call. In
other words, all temporary objects can be destroyed when this method is called.
EndEdit: Commits any changes made after the BeginEdit call. Once
this method is called, changes cannot and should not be rolled back.
The following example illustrates IEditableObject with an implantation of a Customer object.
public class Customer : IEditableObject
{
private bool _transactionStarted =
false;
private String _firstName, _originalFirstName;
private String _lastName, _originalLastName;
private String _phoneNumber, _originalPhoneNumber;
public String FirstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
}
}
public String LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
}
}
public String PhoneNumber
{
get
{
return _phoneNumber;
}
set
{
_phoneNumber = value;
}
}
void IEditableObject.BeginEdit()
{
if (!_transactionStarted)
{
_transactionStarted = true;
_originalFirstName = _firstName;
_originalLastName = _lastName;
_originalPhoneNumber = _phoneNumber;
}
}
void IEditableObject.CancelEdit()
{
if (_transactionStarted)
{
_transactionStarted = false;
_firstName = _originalFirstName;
_lastName = _originalLastName;
_phoneNumber = _originalPhoneNumber;
}
}
void IEditableObject.EndEdit()
{
if (_transactionStarted)
{
_transactionStarted = false;
_originalFirstName = "";
_originalLastName = "";
_originalPhoneNumber = "";
}
}
}
Comments
Be the first to write a comment
You must me logged in to write a comment.