Friday, March 27, 2009

Adding a CheckBox column to your DataGrid

Introduction
There are many articles that explain how to add controls to a DataGrid that can be used to represent and edit data in a format other than a common EditBox, however they all appear to require the programmer to edit the html in the .aspx page(s) rather than use code held solely in the .cs Codebehind files. I have in the past had to implement many different controls that can be used to represent and edit controls within a DataGrid and here I will demonstrate the CheckBox template column with bound CheckBoxes as it is one of the simplest but the the most used control other then the EditBox, and is used to edit fields that are of the boolean type.
ITemplate implementation
Before we can implement the class that will be used as a column within our DataGrid, a class that derives from ITemplate will need to be created that can be used for representing and or editing the data within the grid. In most cases a seperate class will need to be defined for displaying and editing, eg containing a label control or an edit box control. Fortunately we can use the same control, a CheckBox, to represent the boolean state as well as edit it.

public CheckBoxItem(bool editable)
{
readOnly = (editable==true)?false:true;
}
Handling the DataBinding event
Because the CheckBox control is to represent data that is held in the DataGrid then it will need to handle the DataBinding event, which will be called once for each row in the DataGrid. This can be set up in the InstantiateIn method implementation which is the one and only method of the ITemplate interface.

void ITemplate.InstantiateIn(Control container)
{
CheckBox box = new CheckBox();
box.DataBinding += new EventHandler(this.BindData);
container.Controls.Add(box);
}
Processing the DataBinding event
The handler for the DataBinding event is used to set the state of the control depending on the data within the underlying DataGrid as well as set the editable state depending on whether it is being used to view the data or edit the data.

public void BindData(object sender, EventArgs e)
{
CheckBox box = (CheckBox) sender;
DataGridItem container = (DataGridItem) box.NamingContainer;
box.Checked = false;
box.Enabled = (readOnly == true) ? false:true;
string data = ((DataRowView) container.DataItem)[dataField].ToString();
Type type = ((DataRowView)
container.DataItem).DataView.Table.Columns[dataField].DataType;
if (data.Length>0)
{
switch (type.ToString())
{
case "System.Boolean":
if ( data == "True")
{
box.Checked = true;
}
break;
default:
break;
}
}
}
CheckBox Template Column
The class that will be used as the column in our DataGrid will be derived from the System.Web.UI.WebControls.TemplateColumn class. We add objects of the above ITemplate implementation class to the ItemTemplate property, for display, and EditItemTemplate property, for editing.

public CheckBoxColumn()
{
// set the view one as readonly
viewItem = new CheckBoxItem(false);
this.ItemTemplate = viewItem as ITemplate;

// let the edit check box be editable
editItem = new CheckBoxItem(true);
this.EditItemTemplate = editItem as ITemplate;
}
Adding the Column to the DataGrid
The penultimate step is to add the column to the DataGrid itself. Because of the way we have designed the class this is simplicity itself as it can be used in place of a BoundColumn.

CheckBoxColumn checkCol = new CheckBoxColumn();
checkCol.HeaderText = "Boolean Field (Editable)";
checkCol.DataField = "Boolean";

...

DataGrid1.Columns.Add(checkCol);
Extracting the Updated State
The final step is extracting the data from the control itself when it comes to updating or inserting a row. Again we use a similar method as that normally employed however instead of a TextBox we use a CheckBox.

sqlUpdateCommand1.Parameters["@Boolean"].Value
= ((CheckBox)e.Item.Cells[4].Controls[0]).Checked;
AutoPostBack and receiving the CheckedChanged event
It was recently asked if it was possible to receive the CheckedChanged event from the CheckBoxes that were contained within the column. I have since updated the code to handle the scenario where you have a DataGrid with a CheckGridColumn and it is possible to update the field immediately.

Labels:

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home