Adding a Check Box Column to a DataGrid - Cannot get example to work (ASP.NET & C#)

S

sianan

I tried to use the following example, to add a checkbox column to a
DataGrid in an ASP.NET application:
http://www.codeproject.com/aspnet/datagridcheckbox.asp

For some reason, I simply CAN'T get the example to work. I created the
following two classes, provided with the example:

*-*-**-*-*-*-*-*-*-*-*-*-**-*-*-*-*-CheckBoxColumn
Class:-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-**-*-*-*

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

namespace DataGridTest2
{
/// <summary>
/// Summary description for CheckBoxColumn.
/// </summary>
public class CheckBoxColumn
:System.Web.UI.WebControls.TemplateColumn
{
/// <summary>
/// Initialise our CheckBoxColumn.
/// </summary>
public CheckBoxColumn()
{
// set the view one as readonly
//viewItem = new CheckBoxItem(false); // SAW was false
viewItem = new CheckBoxItem(true);
this.ItemTemplate = viewItem as ITemplate;

// let the edit check box be editable
editItem = new CheckBoxItem(true);
this.EditItemTemplate = editItem as ITemplate;
}

/// <summary>
/// Initialise our CheckBoxColumn with an optional
ImmediatePostback capability.
/// </summary>
/// <param name="ImmediatePostback">If true then each change
of state of the
/// CheckBox item
/// will cause an event to be fired immediately on the
server.</param>
public CheckBoxColumn(bool ImmediatePostback)
{
// set the view one as readonly
viewItem = new CheckBoxItem(ImmediatePostback);
this.ItemTemplate = viewItem as ITemplate;

// let the edit check box be editable
editItem = new CheckBoxItem(true);
this.EditItemTemplate = editItem as ITemplate;

AutoPostBack = ImmediatePostback;
}

/// <summary>
/// Occurs when the value of the Checked property changes
between posts to the
/// server.
/// </summary>
/// <remarks>
/// The <b>CheckedChanged</b> event is raised when the value
of the Checked
/// property changes
/// between posts to the server.
/// <b>Note</b> This event does not post the page back to
the server unless the
/// AutoPostBack property is set to true.
/// <b>Note</b> The control must have viewstate enabled for
the
/// <b>CheckedChanged</b> event to work correctly.
/// </remarks>
public event EventHandler CheckedChanged
{
add
{
viewItem.CheckedChanged += value;
editItem.CheckedChanged += value;
}
remove
{
viewItem.CheckedChanged -= value;
editItem.CheckedChanged -= value;
}
}

/// <summary>
/// If true then then each click on a CheckBox will cause an
event to be fired on the
/// server.
/// </summary>
public bool AutoPostBack
{
set
{
viewItem.AutoPostBack = value;
editItem.AutoPostBack = value;
}
get
{
return viewItem.AutoPostBack;
}
}

/// <summary>
/// The DataField that we wish our control to bind to.
/// </summary>
public string DataField
{
get
{
return viewItem.DataField;
}
set
{
viewItem.DataField = value;
editItem.DataField = value;
}
}

/// <summary>
/// Internal storage of the CheckBoxItem that is to be used
for the view state.
/// </summary>
private CheckBoxItem viewItem;

/// <summary>
/// Internal storage of the CheckBoxItem that is to be used for
the edit state.
/// </summary>
private CheckBoxItem editItem;
}
}


*-*-**-*-*-*-*-*-*-*-*-*-**-*-*-*-*-CheckBoxItem
Class:-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-**-*-*-*
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

namespace DataGridTest2
{
/// <summary>
///
/// </summary>
internal class CheckBoxItem : ITemplate
{
/// <summary>
/// The CheckBoxItem constructor
/// </summary>
/// <param name="editable">true if the item is to be in its
editable state, false for the
/// item to be
/// disabled.</param>
public CheckBoxItem(bool editable)
{
readOnly = (editable==true)?false:true;
}

/// <summary>
/// Instantiates the CheckBox that we wish to represent in
this column.
/// </summary>
/// <param name="container">The container into which the
control or controls are
/// added.</param>
void ITemplate.InstantiateIn(Control container)
{
CheckBox box = new CheckBox();
box.DataBinding += new EventHandler(this.BindData);
box.AutoPostBack = autoPostBack;
box.CheckedChanged += new
EventHandler(this.OnCheckChanged);
container.Controls.Add(box);
}

/// <summary>
/// Our CheckChanged event
/// </summary>
public event EventHandler CheckedChanged;

/// <summary>
/// This is a common handler for all the Checkboxes.
/// </summary>
/// <param name="sender">The raiser of this event a
CheckBox.</param>
/// <param name="e">A System.EventArgs that contains the
event data.</param>
private void OnCheckChanged(object sender, EventArgs e)
{
if (CheckedChanged != null)
{
CheckedChanged(sender, e);
}
}

/// <summary>
/// The internal storage for which DataField we are going to
represent.
/// </summary>
private string dataField;

/// <summary>
/// Used to set the DataField that we wish to represent with
this CheckBox.
/// </summary>
public string DataField
{
get
{
return dataField;
}
set
{
dataField=value;
}
}

/// <summary>
/// The internal storage for the AutoPostback flag.
/// </summary>
private bool autoPostBack=false;

/// <summary>
/// Set the AutoPostBack flag. If this is true then each time
a CheckBox is clicked
/// in the Column that contains this item then an event is
raised on the server.
/// </summary>
public bool AutoPostBack
{
set
{
autoPostBack = value;
}
get
{
return autoPostBack;
}
}

/// <summary>
/// Handler for the DataBinding event where we bind the data
for a specific row
/// to the CheckBox.
/// </summary>
/// <param name="sender">The raiser of the event.</param>
/// <param name="e">A System.EventArgs that contains the
event data.</param>
private 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 t =
((DataRowView)container.DataItem).DataView.Table.Columns
[dataField].DataType;
if (data.Length>0)
{
switch (t.ToString())
{
case "System.Boolean":
if (( data == "True") || (data == "true"))
{
box.Checked = true;
}
break;
default:
break;
}
}
}
/// <summary>
/// Internal storage for the readOnly flag.
/// </summary>
private bool readOnly = true;
}
}


*-*-*-*-*-*-*-*-*-*-*-*-*-*Custom Control Code Behind
Page:-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*

namespace DataGridTest2
{
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

/// <summary>
/// Summary description for OrderPickerControl.
/// </summary>
public class OrderPickerControl : System.Web.UI.UserControl
{
protected System.Web.UI.WebControls.DataGrid DataGrid1;
SqlConnection cn;
SqlDataAdapter da;
DataSet ds;

private void Page_Load(object sender, System.EventArgs e)
{
cn= new SqlConnection
("Server=localhost;uid=sa;pwd=pwd;database=testDB");
da= new SqlDataAdapter ("SELECT CustID, IsComplete FROM
Orders ", cn);
ds= new DataSet ();
da.Fill (ds, "Orders");
DataGrid1.DataSource =ds.Tables[0];

// Add the new column to the DataGrid
CheckBoxColumn chkColumn = new CheckBoxColumn();

chkColumn.HeaderText = "Include?";
chkColumn.DataField = "IsComplete";
//chkColumn.AutoPostBack = true;
//chkColumn.CheckedChanged +=new EventHandler(this.o);
DataGrid1.Columns.Add(chkColumn);
DataGrid1.DataBind ();
}



#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web
Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion
}
}


The DataGrid is bound properly, and shows the correct state of the
check boxes for the underlying SQL bit datatype field (IsComplete).
What I can't figure out is how to immediately update the database, once
a checkbox has been checked or unchecked. I was unable to determine how
to do this, based on the example. The IsComplete field contains either
0 values for false, or 1 values for true. Checking the checkbox should
change the 0 values to 1 values (and unchecking should change 1 values
to 0 values). I also want to be able to refresh the DataGrid to show
these changes. (I thought that AutoPostBack would accomplish this, but
I had no luck getting it to work.)

The worst part of it is I know that I'm probably missing something
obvious, due to my lack of experience. Needless to say, any help,
advice, snippets, etc. would be greatly appreciated.

THANKS!!!
 
S

S. Justin Gengo

sianan,

I have code that shows how to find out which checkbox in the datagrid has
been checked on post back. The sample code is in vb.net, but I think you'll
be able to see what it's doing as most of it is using built in objects whos
code will look much the same as c#. If you have any trouble telling what a
routine does I'd be happy to convert that line(s) of code to c#. Just email
me with any questions.

You may find the sample code at:
http://www.aboutfortunate.com?page=codelibrary

Use the search box there to search for: "checkbox in datagrid"

--
Sincerely,

S. Justin Gengo, MCP
Web Developer / Programmer

www.aboutfortunate.com

"Out of chaos comes order."
Nietzsche
sianan said:
I tried to use the following example, to add a checkbox column to a
DataGrid in an ASP.NET application:
http://www.codeproject.com/aspnet/datagridcheckbox.asp

For some reason, I simply CAN'T get the example to work. I created the
following two classes, provided with the example:

*-*-**-*-*-*-*-*-*-*-*-*-**-*-*-*-*-CheckBoxColumn
Class:-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-**-*-*-*

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

namespace DataGridTest2
{
/// <summary>
/// Summary description for CheckBoxColumn.
/// </summary>
public class CheckBoxColumn
:System.Web.UI.WebControls.TemplateColumn
{
/// <summary>
/// Initialise our CheckBoxColumn.
/// </summary>
public CheckBoxColumn()
{
// set the view one as readonly
//viewItem = new CheckBoxItem(false); // SAW was false
viewItem = new CheckBoxItem(true);
this.ItemTemplate = viewItem as ITemplate;

// let the edit check box be editable
editItem = new CheckBoxItem(true);
this.EditItemTemplate = editItem as ITemplate;
}

/// <summary>
/// Initialise our CheckBoxColumn with an optional
ImmediatePostback capability.
/// </summary>
/// <param name="ImmediatePostback">If true then each change
of state of the
/// CheckBox item
/// will cause an event to be fired immediately on the
server.</param>
public CheckBoxColumn(bool ImmediatePostback)
{
// set the view one as readonly
viewItem = new CheckBoxItem(ImmediatePostback);
this.ItemTemplate = viewItem as ITemplate;

// let the edit check box be editable
editItem = new CheckBoxItem(true);
this.EditItemTemplate = editItem as ITemplate;

AutoPostBack = ImmediatePostback;
}

/// <summary>
/// Occurs when the value of the Checked property changes
between posts to the
/// server.
/// </summary>
/// <remarks>
/// The <b>CheckedChanged</b> event is raised when the value
of the Checked
/// property changes
/// between posts to the server.
/// <b>Note</b> This event does not post the page back to
the server unless the
/// AutoPostBack property is set to true.
/// <b>Note</b> The control must have viewstate enabled for
the
/// <b>CheckedChanged</b> event to work correctly.
/// </remarks>
public event EventHandler CheckedChanged
{
add
{
viewItem.CheckedChanged += value;
editItem.CheckedChanged += value;
}
remove
{
viewItem.CheckedChanged -= value;
editItem.CheckedChanged -= value;
}
}

/// <summary>
/// If true then then each click on a CheckBox will cause an
event to be fired on the
/// server.
/// </summary>
public bool AutoPostBack
{
set
{
viewItem.AutoPostBack = value;
editItem.AutoPostBack = value;
}
get
{
return viewItem.AutoPostBack;
}
}

/// <summary>
/// The DataField that we wish our control to bind to.
/// </summary>
public string DataField
{
get
{
return viewItem.DataField;
}
set
{
viewItem.DataField = value;
editItem.DataField = value;
}
}

/// <summary>
/// Internal storage of the CheckBoxItem that is to be used
for the view state.
/// </summary>
private CheckBoxItem viewItem;

/// <summary>
/// Internal storage of the CheckBoxItem that is to be used for
the edit state.
/// </summary>
private CheckBoxItem editItem;
}
}


*-*-**-*-*-*-*-*-*-*-*-*-**-*-*-*-*-CheckBoxItem
Class:-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-**-*-*-*
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

namespace DataGridTest2
{
/// <summary>
///
/// </summary>
internal class CheckBoxItem : ITemplate
{
/// <summary>
/// The CheckBoxItem constructor
/// </summary>
/// <param name="editable">true if the item is to be in its
editable state, false for the
/// item to be
/// disabled.</param>
public CheckBoxItem(bool editable)
{
readOnly = (editable==true)?false:true;
}

/// <summary>
/// Instantiates the CheckBox that we wish to represent in
this column.
/// </summary>
/// <param name="container">The container into which the
control or controls are
/// added.</param>
void ITemplate.InstantiateIn(Control container)
{
CheckBox box = new CheckBox();
box.DataBinding += new EventHandler(this.BindData);
box.AutoPostBack = autoPostBack;
box.CheckedChanged += new
EventHandler(this.OnCheckChanged);
container.Controls.Add(box);
}

/// <summary>
/// Our CheckChanged event
/// </summary>
public event EventHandler CheckedChanged;

/// <summary>
/// This is a common handler for all the Checkboxes.
/// </summary>
/// <param name="sender">The raiser of this event a
CheckBox.</param>
/// <param name="e">A System.EventArgs that contains the
event data.</param>
private void OnCheckChanged(object sender, EventArgs e)
{
if (CheckedChanged != null)
{
CheckedChanged(sender, e);
}
}

/// <summary>
/// The internal storage for which DataField we are going to
represent.
/// </summary>
private string dataField;

/// <summary>
/// Used to set the DataField that we wish to represent with
this CheckBox.
/// </summary>
public string DataField
{
get
{
return dataField;
}
set
{
dataField=value;
}
}

/// <summary>
/// The internal storage for the AutoPostback flag.
/// </summary>
private bool autoPostBack=false;

/// <summary>
/// Set the AutoPostBack flag. If this is true then each time
a CheckBox is clicked
/// in the Column that contains this item then an event is
raised on the server.
/// </summary>
public bool AutoPostBack
{
set
{
autoPostBack = value;
}
get
{
return autoPostBack;
}
}

/// <summary>
/// Handler for the DataBinding event where we bind the data
for a specific row
/// to the CheckBox.
/// </summary>
/// <param name="sender">The raiser of the event.</param>
/// <param name="e">A System.EventArgs that contains the
event data.</param>
private 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 t =
((DataRowView)container.DataItem).DataView.Table.Columns
[dataField].DataType;
if (data.Length>0)
{
switch (t.ToString())
{
case "System.Boolean":
if (( data == "True") || (data == "true"))
{
box.Checked = true;
}
break;
default:
break;
}
}
}
/// <summary>
/// Internal storage for the readOnly flag.
/// </summary>
private bool readOnly = true;
}
}


*-*-*-*-*-*-*-*-*-*-*-*-*-*Custom Control Code Behind
Page:-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*

namespace DataGridTest2
{
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

/// <summary>
/// Summary description for OrderPickerControl.
/// </summary>
public class OrderPickerControl : System.Web.UI.UserControl
{
protected System.Web.UI.WebControls.DataGrid DataGrid1;
SqlConnection cn;
SqlDataAdapter da;
DataSet ds;

private void Page_Load(object sender, System.EventArgs e)
{
cn= new SqlConnection
("Server=localhost;uid=sa;pwd=pwd;database=testDB");
da= new SqlDataAdapter ("SELECT CustID, IsComplete FROM
Orders ", cn);
ds= new DataSet ();
da.Fill (ds, "Orders");
DataGrid1.DataSource =ds.Tables[0];

// Add the new column to the DataGrid
CheckBoxColumn chkColumn = new CheckBoxColumn();

chkColumn.HeaderText = "Include?";
chkColumn.DataField = "IsComplete";
//chkColumn.AutoPostBack = true;
//chkColumn.CheckedChanged +=new EventHandler(this.o);
DataGrid1.Columns.Add(chkColumn);
DataGrid1.DataBind ();
}



#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web
Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion
}
}


The DataGrid is bound properly, and shows the correct state of the
check boxes for the underlying SQL bit datatype field (IsComplete).
What I can't figure out is how to immediately update the database, once
a checkbox has been checked or unchecked. I was unable to determine how
to do this, based on the example. The IsComplete field contains either
0 values for false, or 1 values for true. Checking the checkbox should
change the 0 values to 1 values (and unchecking should change 1 values
to 0 values). I also want to be able to refresh the DataGrid to show
these changes. (I thought that AutoPostBack would accomplish this, but
I had no luck getting it to work.)

The worst part of it is I know that I'm probably missing something
obvious, due to my lack of experience. Needless to say, any help,
advice, snippets, etc. would be greatly appreciated.

THANKS!!!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,016
Latest member
TatianaCha

Latest Threads

Top