OnCheckedChanged event fires more and more times for every time it is clicked
<p>I have an ASP.NET page that contains a gridview.</p>

<p>I have to create columns dynamically based on a datatable, some field type info and some header texts.</p>

<p>I do that by creating templates.</p>

<p>It created the grid fine and all looks good, however when i click a checkbox and the checkedchanged event fires then something odd happens</p>

<p>The first time i click its fine and i get the expected values in the event</p>

<p>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.</p>

<p>And it just keeps going like that</p>

<p>So im stumped!</p>

<p>Here is the code i hope someone can see what i am doing wrong:</p>

<pre><code>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 &lt; 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();
    }
  }
}
</code></pre>

<p><br></p>

<pre><code>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 = "&lt;b&gt;" + HeaderText + "&lt;/b&gt;";
        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);
          check.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


}
</code></pre>
