[Download Code]
Let us first examine how the DataGridHelper control extracts user input from a bound column:
BoundColumn bc = (_dataGrid.Columns[i] as BoundColumn);
if (bc != null)
{
name = bc.DataField;
if (bc.ReadOnly)
{
val = e.Item.Cells[i].Text;
}
else
{
val = ((TextBox)e.Item.Cells[i].Controls[0]).Text;
}
col[name] = val;
}
The code contains the knowledge of the BoundColumn because we know how it works. However, we cannot expect the DataGridHelper control to have the knowledge all existing custom columns and all future custom columns; we cannot keep changing the code of DataGridHelper to add the knowledge of new custom columns. Thus our first step is to define an interface for DataGridHelper and custom columns to work together:
public interface IDataGridColumn
{
void GetValues(TableCell cell, Hashtable col);
}
All custom columns designed to work with DataGridHelper control must implement this interface. The interface has a single method called GetValues. The DataGridHelper will pass a TableCell object and a Hashtable object to the custom column. The custom column class is responsible for extracting the input from the TableCell and adds the field/value pair to the Hashtable. This design can work with custom columns that contain more than one input control. For example, a phone number column could have a control for the area code and another control for the phone number; a zip code column could have a control for the zip code and another control for the zip extension. Since the custom columns are responsible for extracting the inputs, we only need to add the following code in the _dataGrid_UpdateCommand function of DataGridHelper to support custom columns:
IDataGridColumn ic = _dataGrid.Columns[i] as IDataGridColumn;
if (ic != null)
{
ic.GetValues(e.Item.Cells[i], col);
}
That is it. It is so simple! Next, we will introduce two custom DataGrid columns that implement IDataGridColumn interface.