Click here to Skip to main content
Click here to Skip to main content

Adding a CheckBox Column to a DataGrid

By , 29 May 2003
 

Sample Image - DataGridCheckBoxCol.gif

Introduction

A recent project I was working on required a user to select a number of options from a list. Instead of using a mulit-select list box which didn't really fit into the design of the site we decided to make a reusable control that would add a checkbox to a DataGrid.

Using the code

To use the checkbox column in a DataGrid it's simply a matter of registering the tag at the top of the page:

<%@ Register TagPrefix="chkbox" Namespace="DataGridControls" 
    Assembly="DataGridCheckbox" %>

Then to add the checkbox column to the DataGrid:

<asp:DataGrid ID="dgTestGrid" Runat="server" AutoGenerateColumns=True 
    border="0" width="50%">
   <Columns>
   <chkbox:CheckBoxColumn/>
   </Columns>
  </asp:DataGrid>

The CheckBoxColumn class is pretty straight forward:

using System;
using System.Collections;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace DataGridControls
{
 /// <summary>
 /// CheckBoxColumn Derives from DataGrid Column
 /// </summary>
 public class CheckBoxColumn : DataGridColumn
 {
    public CheckBoxColumn(): base()
      {
      }
  
      public override void InitializeCell(TableCell cell, 
        int columnIndex, ListItemType itemType) 
      {
           //let the base class initialize the cell
           base.InitializeCell(cell, columnIndex, itemType);



           //we don't want to add a checkbox to the header.
           if(    itemType == ListItemType.EditItem || 
            itemType == ListItemType.Item || 
            itemType == ListItemType.AlternatingItem || 
            itemType == ListItemType.SelectedItem){

                HtmlInputCheckBox checkbox = new HtmlInputCheckBox();
                //assign an ID that we can use to find the control later
                checkbox.ID = "checkboxCol";
                cell.Controls.Add(checkbox);
           }
      }
      public Int32[] SelectedIndexes 
      {
           get 
           {
                ArrayList selectedIndexList = new ArrayList();
                //iterate each DataGridItem and find our checkbox
                foreach( DataGridItem item in this.Owner.Items ) 
                {
                     HtmlInputCheckBox chkBox = 
                        (HtmlInputCheckBox) item.FindControl("checkboxCol");
     
                     //If it's selected then add it to our ArrayList
                     if ( chkBox != null && chkBox.Checked )  
                     {
                          selectedIndexList.Add( item.ItemIndex );
                     } 
     
                }
                return (Int32[])selectedIndexList.ToArray(typeof( 
                        System.Int32 ) );
           }
      }
      public object[] SelectedDataKeys 
      {
           get 
           {
                //Just iterate each of the selectedindexes and 
                //match it up to the datakey field
                ArrayList dataKeyList = new ArrayList();
                //make sure the datakeys have some values
                if(this.Owner.DataKeys.Count > 0)
                {
                     foreach( Int32 selectedIndex in SelectedIndexes ) 
                     {
     
                          object DataKey = 
                              (this.Owner.DataKeys[selectedIndex].ToString());
                          dataKeyList.Add(DataKey);
                     }
                }
                return (object[])dataKeyList.ToArray(typeof( object ) );
           }
   
      }
   }
}

The class exposes 2 properties: 

  • SelectedDataKeys: Returns an ArrayList with the DataKey values
  • SelectedIndexes: Returns an Int32[] with the selectedIndex values

To find out which checkbox has been selected:

//On our button's Onclick

protected void btnSubmit_Click(object sender, EventArgs e)
  {
   //Get our checkboxcolumn, we know it's position is 0
   CheckBoxColumn chkbox = (CheckBoxColumn) dgTestGrid.Columns[0];
   
   foreach(object datakeyfield in chkbox.SelectedDataKeys)
   {
    Response.Write(datakeyfield.ToString() + "<br>");
   }
  }

That's pretty much it, the DataKeyField of the DataGrid can be of any type. The sample I've included binds a DataTable to the DataGrid, you can change the DataKeyField from "ID" (int) to "Name" (string) to see the code working with different types.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Dan_P
Web Developer
Australia Australia
Member
I've been programming for a few years now. I blog regularly at httpcode.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralPretty handymemberJBress8 Jun '11 - 3:56 
Thank you
 
However, it seems there is a small bug where you retrieve the data keys :
object DataKey = (this.Owner.DataKeys[selectedIndex].ToString());
 
As a data key can be of any type, you should not convert the key to string and simply do :
object DataKey = this.Owner.DataKeys[selectedIndex];
 
My 2 cents
GeneralC#Net2003 - Window Application Add CheckBox In DataGridmemberTeeLeong4 Nov '09 - 8:56 
Hi Dan_P,
 
I read your submission and it was very informative. Thanks to you for that. I tried testing the script on DataGrid in Windows Based Application instead of Internet ASP.NET and I could not get it to work. Could please help me out on Windows based application.
 
Thanks.
 
Have a Good Day
Lennie Kuah

Generalbrowse buttonmemberMember 444235011 Apr '08 - 1:30 
i am going to use asp.net 1.1 how ia can browse a file in asp.net1.1
GeneralI can't load the projectmemberGFJ16 Jul '07 - 5:12 

I like to load the project , build it and be able to modify it
 
I get an error about wanting to install web dev components. Anyway,
 
what type of project is it? Asp.net web app or asp.net control.
 

GeneralThe same but for VB.NETmemberTheSilentman14 Feb '07 - 3:47 
I have to do the same thing but in Visual Basic .net, does someone has it? thanks.Roll eyes | :rolleyes:
QuestionWhat will happen if more one page data will it work properlymemberMember #75098521 Jan '07 - 21:06 
What will happen if more one page data will it work properly
QuestionWhat about TemplateColumnmemberSenFo9 Jan '06 - 8:35 
Can't you already do this in a DataGrid using a TemplateColumn?
AnswerRe: What about TemplateColumnmemberjeganji14 Dec '06 - 18:45 
You can use <asp:TemplateColumn> tag
column under section in the datagrid
 
<asp:TemplateColumn>

<asp:CheckBox id="chkSelect" GroupName="grpSelect" runat="server">


 
Jegan

GeneralRe: What about TemplateColumnmembererax dan13 Aug '08 - 22:17 
Hi, if we wanna add also one more checkbox to select all or unselect all, what should we do? I think this will help us writing such communication based pages like mails, i had this problem on my page, if u are interested i will be glad thanks
GeneralModified Code for Server-Side Select-DeselectAllmembersikemullivan15 Oct '05 - 9:11 
Ok.... I just went ahead and modified some code for everyone so that they can easily add a checkbox in the header which allows select/deselect all. This is server-side so if you have alot of traffic i would advise not to use this; instead use javascript. Whats nice about this code is that it is just a modification in the class and no where else.
 

using System;
using System.Collections;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace DataGridControls
{
///
/// CheckBoxColumn Derives from DataGrid Column
///

public class CheckBoxColumn : DataGridColumn
{
public CheckBoxColumn(): base()
{
}


public override void InitializeCell(TableCell cell,
int columnIndex, ListItemType itemType)
{
//let the base class initialize the cell
base.InitializeCell(cell, columnIndex, itemType);

//add checkbox to header
if(itemType == ListItemType.Header)
{
CheckBox headerCheckBox = new CheckBox();
headerCheckBox.ID = "chkAll";
headerCheckBox.CheckedChanged += new EventHandler(this.headerCheckBox_CheckedChanged);
headerCheckBox.AutoPostBack = true;

cell.Controls.Add(headerCheckBox);
}
 
//now we add a checkbox to the rest of the cells
if( itemType == ListItemType.EditItem ||
itemType == ListItemType.Item ||
itemType == ListItemType.AlternatingItem ||
itemType == ListItemType.SelectedItem)
{
 
HtmlInputCheckBox checkbox = new HtmlInputCheckBox();
checkbox.Name = "checkboxCol";
checkbox.ID = "checkboxCol";
//assign an ID that we can use to find the control later
cell.Controls.Add(checkbox);
}
 
}
 
private void headerCheckBox_CheckedChanged(object sender, EventArgs e)
{
foreach (DataGridItem item in this.Owner.Items)
{
//iterate each DataGridItem and find our checkbox
HtmlInputCheckBox chkBox = (HtmlInputCheckBox) item.FindControl("checkboxCol");
//now set that checkboxCol value = to selected
if(chkBox.Checked == false)
chkBox.Checked = true;
else
chkBox.Checked = false;

}
}



public Int32[] SelectedIndexes
{
get
{
ArrayList selectedIndexList = new ArrayList();
//iterate each DataGridItem and find our checkbox
foreach( DataGridItem item in this.Owner.Items )
{
HtmlInputCheckBox chkBox =
(HtmlInputCheckBox) item.FindControl("checkboxCol");

//If it's selected then add it to our ArrayList
if ( chkBox != null && chkBox.Checked )
{
selectedIndexList.Add( item.ItemIndex );
}

}
return (Int32[])selectedIndexList.ToArray(typeof(
System.Int32 ) );
}
}
public object[] SelectedDataKeys
{
get
{
//Just iterate each of the selectedindexes and
//match it up to the datakey field
ArrayList dataKeyList = new ArrayList();
//make sure the datakeys have some values
if(this.Owner.DataKeys.Count > 0)
{
foreach( Int32 selectedIndex in SelectedIndexes )
{

object DataKey =
(this.Owner.DataKeys[selectedIndex].ToString());
dataKeyList.Add(DataKey);
}
}
return (object[])dataKeyList.ToArray(typeof( object ) );
}

}
}
}

 

 
Sully
GeneralRe: Modified Code for Server-Side Select-DeselectAllmemberlowlandr30 Dec '05 - 5:01 
If you check or uncheck some boxes then do a select/deselect all, it simply
flips the state of the checkboxes, that is not what I needed so...
I modified this function in order to set all check boxes to the header box state (all checked or all unchecked).
 
private void headerCheckBox_CheckedChanged(object sender, EventArgs e)
{
//grab the sender state here
CheckBox headerBox;
headerBox = (CheckBox) sender;
bool l_bState = headerBox.Checked;

foreach (DataGridItem item in this.Owner.Items)
{
//iterate each DataGridItem and find our checkbox
HtmlInputCheckBox chkBox = (HtmlInputCheckBox) item.FindControl("checkboxCol");

//now set the checkbox to the sender state
chkBox.Checked = l_bState;
}
}
 

//low

GeneralRe: Modified Code for Server-Side Select-DeselectAllmemberSilverSabre18 Nov '08 - 4:41 
Hi there
 
for some reason I cannot get the postback to hit the checked event for the header...
 
Dunno What i am doing wrong.
 
Here is my code:
 

using System;
using System.Collections;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
namespace DataGridControls
{
///
/// CheckBoxColumn Derives from DataGrid Column
///
public class CheckBoxColumn : DataGridColumn
{
public CheckBoxColumn()
: base()

{

}
 
private static String Name = "";

 
public String CheckBoxColumnName
{
get { return Name; }
set { Name = value; }
}
 

public override void InitializeCell(TableCell cell, int columnIndex, ListItemType itemType)
{


try
{
CheckBoxColumnName = this.Owner.ID;
}
catch (Exception ex)
{
 
}
//let the base class initialize the cell
base.InitializeCell(cell, columnIndex, itemType);
 

//add checkbox to header
if (itemType == ListItemType.Header)
{

CheckBox headerCheckBox = new CheckBox();
headerCheckBox.ID = CheckBoxColumnName + "_chkAll";
headerCheckBox.CheckedChanged += new EventHandler(this.headerCheckBox_CheckedChanged);
// headerCheckBox.AutoPostBack = true;
 
cell.Controls.Add(headerCheckBox);
}
 
//now we add a checkbox to the rest of the cells

if (itemType == ListItemType.EditItem ||
itemType == ListItemType.Item ||
itemType == ListItemType.AlternatingItem ||
itemType == ListItemType.SelectedItem)
{
 
HtmlInputCheckBox checkbox = new HtmlInputCheckBox();
checkbox.Name = CheckBoxColumnName + "_checkboxCol";
checkbox.ID = CheckBoxColumnName + "_checkboxCol" ;
//assign an ID that we can use to find the control later
cell.Controls.Add(checkbox);

}


}
 
private void headerCheckBox_CheckedChanged(object sender, EventArgs e)
{
//grab the sender state here
CheckBox headerBox;
headerBox = (CheckBox)sender;
bool l_bState = headerBox.Checked;
 
foreach (DataGridItem item in this.Owner.Items)
{
//iterate each DataGridItem and find our checkbox
HtmlInputCheckBox chkBox = (HtmlInputCheckBox)item.FindControl(CheckBoxColumnName + "_checkboxCol");
 
//now set the checkbox to the sender state
chkBox.Checked = l_bState;
}
}

 

 
public Int32[] SelectedIndexes
{
get
{
ArrayList selectedIndexList = new ArrayList();
//iterate each DataGridItem and find our checkbox

foreach (DataGridItem item in this.Owner.Items)
{
HtmlInputCheckBox chkBox =
(HtmlInputCheckBox)item.FindControl(CheckBoxColumnName + "_checkboxCol");
 
//If it's selected then add it to our ArrayList
if (chkBox != null && chkBox.Checked)
{
selectedIndexList.Add(item.ItemIndex);
}

}
return (Int32[])selectedIndexList.ToArray(typeof(
System.Int32));
}
}
public object[] SelectedDataKeys
{
get
{
//Just iterate each of the selectedindexes and
//match it up to the datakey field
ArrayList dataKeyList = new ArrayList();
//make sure the datakeys have some values
if (this.Owner.DataKeys.Count > 0)
{
foreach (Int32 selectedIndex in SelectedIndexes)
{
 
object DataKey =
(this.Owner.DataKeys[selectedIndex].ToString());
dataKeyList.Add(DataKey);
}
}
return (object[])dataKeyList.ToArray(typeof(object));
}
 
}
}
}
 

 

any ideas?
pretty please?
GeneralError with Assemblymembersikemullivan12 Oct '05 - 10:56 
I think my problem is with the referencing. I'm not exactly sure where I'm supposed to place the class file. Should I start a new class library and place it in there?????
 
My assembly load trace
 
=== Pre-bind state information ===
LOG: DisplayName = DataGridCheckbox
(Partial)
LOG: Appbase = file:///c:/inetpub/wwwroot/donationnationCS
LOG: Initial PrivatePath = bin
Calling assembly : (Unknown).
===
 
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Post-policy reference: DataGridCheckbox
LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/Temporary ASP.NET Files/donationnationcs/baaf210b/9fa24547/DataGridCheckbox.DLL.
LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/Temporary ASP.NET Files/donationnationcs/baaf210b/9fa24547/DataGridCheckbox/DataGridCheckbox.DLL.
LOG: Attempting download of new URL file:///c:/inetpub/wwwroot/donationnationCS/bin/DataGridCheckbox.DLL.
LOG: Attempting download of new URL file:///c:/inetpub/wwwroot/donationnationCS/bin/DataGridCheckbox/DataGridCheckbox.DLL.
LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/Temporary ASP.NET Files/donationnationcs/baaf210b/9fa24547/DataGridCheckbox.EXE.
LOG: Attempting download of new URL file:///C:/WINDOWS/Microsoft.NET/Framework/v1.1.4322/Temporary ASP.NET Files/donationnationcs/baaf210b/9fa24547/DataGridCheckbox/DataGridCheckbox.EXE.
LOG: Attempting download of new URL file:///c:/inetpub/wwwroot/donationnationCS/bin/DataGridCheckbox.EXE.
LOG: Attempting download of new URL file:///c:/inetpub/wwwroot/donationnationCS/bin/DataGridCheckbox/DataGridCheckbox.EXE.
 

Please help..... Thankyou
 
Sully
General2 CHECKBOXCOLUMN in a DatagridmemberOlog-hai29 Apr '05 - 10:08 
Hi
 
this class support 2 CHECKBOXCOLUMN ?
 
I wanna know if someone have added 2 CHECKBOXCOLUMN in the same datagrid ?
 
i got this error
 
Multiple controls with the same ID 'checkboxCol' were found. FindControl requires that controls have unique IDs.
 


 
______________
Olog-hai
Near to Mordor
hugues_gauthier@hotmail.com
GeneralRe: 2 CHECKBOXCOLUMN in a DatagridmemberSilverSabre18 Nov '08 - 0:18 
I have to use Two datagrids within a single page, both with checkboxes. Is there any other way to use this control, that will get around the need to use Findcontrol?
 
With more than one checkbox column the findcontrol generates the error Olog-hai pointed out
GeneralData type undefinedmemberDustin Boston12 Jan '05 - 10:14 
Okay,
 
I add the project to my solution, create a reference to the dll, and add the @ Register directive at the top of my form. Runs great, and is so easy to use!
 
If I try to retreive the values as you have described I get a Data type undefined error. Why? I am using a code-behind. Is there something you need to do to make it work in a code-behind?
 
Thanks!
 
Dustin Boston
GeneralCheckbox in datagridmemberfredo_lefran3 Jan '05 - 23:35 
Hello,
 
I used your code in order to add a checkbox column to my datagrid.
 
So I would like to put in the header a checkbox to select/Deselectall.
 
I know put the checkbox in the header but i don't know how i have to program .
 
Thank you for your help.
 
Fred.
Questioncheckbox initial value?memberJ_T_C29 Jun '04 - 11:04 
So, anyway to set the initial value of the checkbox based on the dataset you have??
AnswerRe: checkbox initial value?memberSukim14 Aug '04 - 23:30 
i added the following inorder to set the inital values
 
in the webform.aspx added these lines
 
ArrayList selArray = new ArrayList();
foreach(DataRow dr in Ds.Tables[0].Rows)
{
selArray.Add(dr.ItemArray.GetValue(1));
}
 
second column in my datatable will have value "CHECK" or "UNCHECK" from my database.
 

in the web contorl i added one more method
 

public void setSelectedIndex(ArrayList selArray)
{
int indexchk = 0;
foreach( DataGridItem item in this.Owner.Items )
{
HtmlInputCheckBox chkBox = (HtmlInputCheckBox) item.FindControl("checkboxCol");
 
//If it's selected then add it to our ArrayList
if ( chkBox != null && selArray[indexchk].Equals("CHECK") )
chkBox.Checked = true;
else
chkBox.Checked = false;
 
indexchk++;
}
}
 

And i am able to achieve the result.
However I have little different problem now.
ny dataset will vary on each post back.
First time it checks accordingly but when i postback it doesn't change
The checkbox values are not changing and the initial values are retained.
 
can somebody help on this.

GeneralRe: checkbox initial value?memberSukim15 Aug '04 - 1:15 
I am able to get the correct values if i set the checkboxes disabled.
But i dont want it that way. can any body help it.
Generalthe example will show error in VS.net 2003memberhardyhe9 May '04 - 17:01 




 
because the chkbox are not allow in new enviorment.

 
So am I
GeneralRe: the example will show error in VS.net 2003memberjsnook18 Jun '04 - 8:12 
I don't know what this guy is talking about. As long as you set your references, it works just fine. Also, this guy has poor communication skills
 
SNook
GeneralSelect/Deselect Allmemberpeterwi19 Dec '03 - 12:43 
Hi,
 
Using your checkbox column object, is there a simple way to select or deselect all checkboxes in the column ?
 
Thanks,
 
Peter
Generala bug ....membertopcn22 Jun '03 - 8:07 
i have setted the DataKeyField of DataGrid on desin view,then,when i view a page on IE,a error message say 'SelectedIndexes is only read', ......Confused | :confused:
GeneralRe: a bug ....memberjsnook18 Jun '04 - 7:03 
Yeah, I had that too. You have to go into the HTML and edit the checkbox attributes to remove it.

 
Snook

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 30 May 2003
Article Copyright 2003 by Dan_P
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid