OnCheckedChanged event fires more and more times for every time it is clicked
I have an ASP.NET page that contains a gridview.
I have to create columns dynamically based on a datatable, some field type info and some header texts.
I do that by creating templates.
It created the grid fine and all looks good, however when i click a checkbox and the checkedchanged event fires then something odd happens
The first time i click its fine and i get the expected values in the event
But the second time then the event gets fired with the values from the first time and then again with the values from the checkbox that i actually clicked.. The third time the event gets fired 3 times, first 2 times with the old values and the third with the correct value.
And it just keeps going like that
So im stumped!
Here is the code i hope someone can see what i am doing wrong:
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
namespace GridTest
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DoTheGridView();
}
public void CreateGrid(DataTable table, string[] types, string[] headers)
{
try
{
for (int i = 0; i < table.Columns.Count; i++)
{
TemplateField field = new TemplateField();
//header template
field.HeaderTemplate = new GridViewHandler(ListItemType.Header, table.Columns[i].ColumnName, types[i], headers[i]);
//item template
field.ItemTemplate = new GridViewHandler(ListItemType.Item, table.Columns[i].ColumnName, types[i], headers[i]);
//edit template
field.EditItemTemplate = new GridViewHandler(ListItemType.EditItem, table.Columns[i].ColumnName, types[i], headers[i]);
grid.Columns.Add(field);
}
}
catch (Exception)
{
throw;
}
}
public void DoTheGridView()
{
DataTable table = SqlHelper.GetData();
string[] types = Regex.Split("String,String,String,String,String,CheckBox", ",");
string[] headers = Regex.Split("UserID,License Key,Name,Company,Email,Xpress", ",");
CreateGrid(table, types, headers);
table.DefaultView.RowFilter = "navn like 'Anders%'";
table.DefaultView.Sort = "navn DESC";
grid.DataSource = table.DefaultView;
grid.DataBind();
}
}
}
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Specialized;
using GridTest;
public class GridViewHandler : ITemplate
{
#region data memebers
ListItemType ItemType;
string FieldName;
string InfoType;
string HeaderText;
#endregion
#region constructor
public GridViewHandler(ListItemType item_type, string field_name, string info_type, string header_text)
{
ItemType = item_type;
FieldName = field_name;
InfoType = info_type;
HeaderText = header_text;
}
#endregion
#region Methods
public void InstantiateIn(System.Web.UI.Control Container)
{
switch (ItemType)
{
case ListItemType.Header:
Literal header_ltrl = new Literal();
header_ltrl.Text = "<b>" + HeaderText + "</b>";
Container.Controls.Add(header_ltrl);
break;
case ListItemType.Item:
switch (InfoType)
{
case "CheckBox":
CustomCheckBox check = new CustomCheckBox();
check.ID = "CheckBox";
check.AutoPostBack = true;
//check.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
check.DataBinding += new EventHandler(OnDataBinding);
Container.Controls.Add(check);
break;
case "Command":
ImageButton edit_button = new ImageButton();
edit_button.ID = "edit_button";
edit_button.ImageUrl = "~/images/edit.gif";
edit_button.CommandName = "Edit";
edit_button.Click += new ImageClickEventHandler(edit_button_Click);
edit_button.ToolTip = "Edit";
Container.Controls.Add(edit_button);
ImageButton delete_button = new ImageButton();
delete_button.ID = "delete_button";
delete_button.ImageUrl = "~/images/delete.gif";
delete_button.CommandName = "Delete";
delete_button.ToolTip = "Delete";
delete_button.OnClientClick = "return confirm('Are you sure to delete the record?')";
Container.Controls.Add(delete_button);
/* Similarly add button for insert.
* It is important to know when 'insert' button is added
* its CommandName is set to "Edit" like that of 'edit' button
* only because we want the GridView enter into Edit mode,
* and this time we also want the text boxes for corresponding fields empty*/
ImageButton insert_button = new ImageButton();
insert_button.ID = "insert_button";
insert_button.ImageUrl = "~/images/insert.bmp";
insert_button.CommandName = "Edit";
insert_button.ToolTip = "Insert";
insert_button.Click += new ImageClickEventHandler(insert_button_Click);
Container.Controls.Add(insert_button);
break;
default:
Label field_lbl = new Label();
field_lbl.ID = FieldName;
field_lbl.Text = String.Empty; //we will bind it later through 'OnDataBinding' event
field_lbl.DataBinding += new EventHandler(OnDataBinding);
Container.Controls.Add(field_lbl);
break;
}
break;
case ListItemType.EditItem:
if (InfoType == "Command")
{
ImageButton update_button = new ImageButton();
update_button.ID = "update_button";
update_button.CommandName = "Update";
update_button.ImageUrl = "~/images/update.gif";
if ((int)new Page().Session["InsertFlag"] == 1)
update_button.ToolTip = "Add";
else
update_button.ToolTip = "Update";
update_button.OnClientClick = "return confirm('Are you sure to update the record?')";
Container.Controls.Add(update_button);
ImageButton cancel_button = new ImageButton();
cancel_button.ImageUrl = "~/images/cancel.gif";
cancel_button.ID = "cancel_button";
cancel_button.CommandName = "Cancel";
cancel_button.ToolTip = "Cancel";
Container.Controls.Add(cancel_button);
}
else if (InfoType == "CheckBox")
{
CustomCheckBox check = new CustomCheckBox();
check.ID = "CheckBox";
//check.AutoPostBack = true;
//check.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
chec开发者_如何学编程k.DataBinding += new EventHandler(OnDataBinding);
Container.Controls.Add(check);
}
else// for other 'non-command' i.e. the key and non key fields, bind textboxes with corresponding field values
{
TextBox field_txtbox = new TextBox();
field_txtbox.ID = FieldName;
field_txtbox.Text = String.Empty;
// if Inert is intended no need to bind it with text..keep them empty
if ((int)new Page().Session["InsertFlag"] == 0)
field_txtbox.DataBinding += new EventHandler(OnDataBinding);
Container.Controls.Add(field_txtbox);
}
break;
}
}
#endregion
#region Event Handlers
public void checkbox_CheckedChanged(object sender, EventArgs e)
{
CustomCheckBox cbox = (CustomCheckBox)sender;
string hej = cbox.ID.ToString();
}
//just sets the insert flag ON so that we ll be able to decide in OnRowUpdating event whether to insert or update
protected void insert_button_Click(Object sender, EventArgs e)
{
new Page().Session["InsertFlag"] = 1;
}
//just sets the insert flag OFF so that we ll be able to decide in OnRowUpdating event whether to insert or update
protected void edit_button_Click(Object sender, EventArgs e)
{
new Page().Session["InsertFlag"] = 0;
}
private void OnDataBinding(object sender, EventArgs e)
{
object bound_value_obj = null;
Control ctrl = (Control)sender;
IDataItemContainer data_item_container = (IDataItemContainer)ctrl.NamingContainer;
int rowid = data_item_container.DataItemIndex;
bound_value_obj = DataBinder.Eval(data_item_container.DataItem, FieldName);
switch (ItemType)
{
case ListItemType.Item:
if (InfoType == "CheckBox")
{
string value = bound_value_obj.ToString();
bool ischecked = false;
if (value.ToLower() == "true")
ischecked = true;
CustomCheckBox cbox = (CustomCheckBox)sender;
cbox.Checked = ischecked;
cbox.RowID = rowid;
cbox.FieldName = FieldName;
cbox.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
}
else
{
Label field_ltrl = (Label)sender;
field_ltrl.Text = bound_value_obj.ToString();
}
break;
case ListItemType.EditItem:
if (InfoType == "CheckBox")
{
string value = bound_value_obj.ToString();
bool ischecked = false;
if (value.ToLower() == "true")
ischecked = true;
CustomCheckBox cbox = (CustomCheckBox)sender;
cbox.Checked = ischecked;
cbox.RowID = rowid;
cbox.FieldName = FieldName;
}
else
{
TextBox field_txtbox = (TextBox)sender;
field_txtbox.Text = bound_value_obj.ToString();
}
break;
}
}
#endregion
}
You might want to check that you are ensuring that you are only binding to an event once only. From first glance, it seems that you are not checking this. From your post description, it seems that this is happening.
cbox.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
If you are not sure where to bind it to ensure it only happens once, you can unbind it before the start of the function to ensure at most 1 is connected at a time:
For example:
switch (ItemType)
{
case ListItemType.Item:
if (InfoType == "CheckBox")
{
string value = bound_value_obj.ToString();
bool ischecked = false;
if (value.ToLower() == "true")
ischecked = true;
CustomCheckBox cbox = (CustomCheckBox)sender;
cbox.CheckedChanged -= new EventHandler(checkbox_CheckedChanged);
cbox.Checked = ischecked;
cbox.RowID = rowid;
cbox.FieldName = FieldName;
cbox.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
}
else
{
Label field_ltrl = (Label)sender;
field_ltrl.Text = bound_value_obj.ToString();
}
break;
I must admit I haven't read the entire source (it's quite lengthy and malformed), but in my experience this type of behavior is caused by attaching an event handler in code that is triggered by the same event. So for the first event it would perform ok, the second time you have two event handlers, then 4 and so on.
Edit:
You can check if there already is an event handler like this:
if (cbox.CheckedChanged==null){
//bind the event handler
}
精彩评论