65.9K
CodeProject is changing. Read more.
Home

Implementing a Custom DataGrid Selection Column Step by Step

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.18/5 (5 votes)

Feb 20, 2008

CPOL

3 min read

viewsIcon

27345

downloadIcon

267

The purpose of this article is to demonstrate the architecture of the DataGrid TemplateColumn class using an example implementation of a DataGrid custom selection column.

Introduction

The purpose of this article is to demonstrate the architecture of the DataGrid TemplateColumn class using an example implementation of a DataGrid custom selection column. We should be able to design more complex custom columns easily. After reading this, you will be able to implement a DataGrid progress column and other custom columns.

Abstract

Let us examine TemplateColumn first. You will find the following definition of the TemplateColumn class in the .NET framework:

public class TemplateColumn : DataGridColumn
{
    public TemplateColumn();
    public virtual ITemplate EditItemTemplate { get; set; }
    public virtual ITemplate FooterTemplate { get; set; }
    public virtual ITemplate HeaderTemplate { get; set; }
    public virtual ITemplate ItemTemplate { get; set; }
    public override void InitializeCell(TableCell cell, 
                    int columnIndex, ListItemType itemType);
}

As the definition suggests we can set these properties to any class that implements the ITemplate interface.

To implement a selection column in a data grid, we need to add a TemplateColumn that will display a check box in its header template and also a check box for each of the item templates, like in the above figure.

Step 1: Adding the Required Classes

Add a class in your project named “CheckBoxColumn” and extend it from the System.Web.UI.WebControls.TemplateColumn class. Your class definition should look like:

public class CheckBoxColumn:TemplateColumn
{
    .. ... ... 
}

Add two more classes in your project named “CheckBoxFieldTemplate” and “CheckBoxHeaderTemplate”; both should implement the ITemplate interface. Their definition should look like this:

class CheckBoxFieldTemplate:ITemplate
{
    public void InstantiateIn(Control container)
    {
    }
}

class CheckBoxHeaderTemplate:ITemplate
{
    public void InstantiateIn(Control container)
    {
    }
}

The ITemplate interface contains only a single function: void InstantiateIn(Control container);. When implemented by a class, it defines the System.Web.UI.Control object that child controls and templates belong to. These child controls are in turn defined within an inline template.

Step 2: Adding a CheckBox and Attaching the JavaScript

We need to display a checkbox in both the header and the item template, so in both classes, our InstantiateIn method should look like this:

public void InstantiateIn(Control container)
{
    DataGridItem container =(DataGridItem)container;
    CheckBox chkSelect = new CheckBox();
    chkSelect.DataBinding += new EventHandler(this.OnDataBinding);
    chkSelect.Attributes.Add("onClick", 
      "return HighLightRow(this," + container.ItemIndex.ToString() + 
      ",'" + this._selectColor.Name + "','" + this._unSelectColor.Name + "');");
    container.Controls.Add(chkSelect);
}

Step 3: Assigning ItemTemplates to a Custom Column

We have our required templates that can be used with our custom column. Now, you have to set two inherited properties of our custom column ItemTemplate and HeaderTemplate.

As the definition suggests, you can set these properties to any class that implements the ITemplate interface. Our classes created in step one fulfills that requirement. So, the custom template column class should look like this:

public class CheckBoxColumn:TemplateColumn
{
    private CheckBoxHeaderTemplate CheckBoxHeaderTemplate = new CheckBoxHeaderTemplate();
    private CheckBoxFieldTemplate CheckBoxFieldTemplate = new CheckBoxFieldTemplate(); 
    public CheckBoxColumn():base()
    {
        this.ItemTemplate = CheckBoxFieldTemplate;
        this.HeaderTemplate = CheckBoxHeaderTemplate;
    }
}

Now, you can add these columns to a data grid by referencing its assembly in your page. Add the appropriate JavaScript for the header checkbox and for the item checkbox.

Step 4: Adding the Databinding Functionality

Finally, we need to implement the databinding functionality so our custom column will also work as a databound column if required. Expose a property in your CheckBoxColumn class named “DataField”. Modify the constructor of CheckBoxFieldTemplate to accept the column name to bind with. Now, override the databinding event of ITemplate using the following code:

public void OnDataBinding(object sender, EventArgs e)
{
    if (this._columnName.Length > 0)
    {
        CheckBox chk = (CheckBox)sender;
        DataGridItem container = (DataGridItem)chk.NamingContainer;
        chk.Checked = Convert.ToBoolean(
           ((DataRowView)container.DataItem)[this._columnName]);
    }
}

Step 5: Download the Demo and Attach the JavaScript

Download Jscript2.js attached in the demo project and add it to your project directory and place its reference on the top of your page.

Using the Code

You are able to add a check box column with Check All, Uncheck All, and highlight selected rows, and also have databinding functionality by just adding this custom checkbox column in your grid, as follows:

<CC1:CheckBoxColumn> </CC1:CheckBoxColumn>

Points of Interest

You are able to make custom columns like progress columns, and fixed length columns that display .... after a specified length of string, and can reuse these all over your application.