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!!!
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!!!