title: Dynamic Gridview - item template control event handling
body: <p>I have created a custom gridview control that inherits the asp.net gridview. I am required to use item templates in this gridview. I create a method in my custom gridview that generates the item template.</p>
  
  <pre><code>public void addTemplateField(Control headerTemplateControl, Control itemTemplateControl, EventHandler bindHandler, EventHandler initHandler, string headerText, string sortExpression, bool isVisible, int? heightPx, int? widthPercent)
  {
      TemplateField tField = new TemplateField();
  
      if (headerTemplateControl != null)
          tField.HeaderTemplate = new GridViewTemplate(ListItemType.Header, headerTemplateControl);
  
      if (bindHandler != null &amp;&amp; initHandler != null)
          tField.ItemTemplate = new GridViewTemplate(ListItemType.Item, itemTemplateControl, bindHandler, initHandler);
  
      else if (bindHandler != null)
          tField.ItemTemplate = new GridViewTemplate(ListItemType.Item, itemTemplateControl, bindHandler, false);
  
      else if (initHandler != null)
          tField.ItemTemplate = new GridViewTemplate(ListItemType.Item, itemTemplateControl, initHandler, true);
  
      else
          tField.ItemTemplate = new GridViewTemplate(ListItemType.Item, itemTemplateControl);
  
      if (sortExpression != null)
          tField.SortExpression = sortExpression;
  
      tField.Visible = isVisible;
  
      if (headerText != null)
          tField.HeaderText = headerText;
  
      if (heightPx.HasValue)
          tField.HeaderStyle.Height = new Unit(heightPx.Value, UnitType.Pixel);
  
      if (widthPercent.HasValue)
          tField.HeaderStyle.Height = new Unit(widthPercent.Value, UnitType.Percentage);
  
      addColumnField(tField);
  }
  </code></pre>
  
  <p>And this is how I have implemented ITemplate</p>
  
  <pre><code>public class GridViewTemplate : ITemplate
  {
      int _controlCount = 0;
      ListItemType _templateType;
      EventHandler _bindHandler;
      EventHandler _initHandler;
      Control _control;
      public GridViewTemplate(ListItemType type, Control control)
      {
          this._templateType = type;
          this._control = control;
      }
      public GridViewTemplate(ListItemType type, Control control, EventHandler Handler, bool isInitHandler)
      {
          this._templateType = type;
          this._control = control;
          if (isInitHandler)
              this._initHandler = Handler;
          else
              this._bindHandler = Handler;
      }
      public GridViewTemplate(ListItemType type, Control control, EventHandler bindHandler, EventHandler initHandler)
      {
          this._templateType = type;
          this._control = control;
          this._bindHandler = bindHandler;
          this._initHandler = initHandler;
      }
      public Control Copy(Control ctrlSource)
      {
          Type _type = ctrlSource.GetType();
          Control ctrlDest = (Control)Activator.CreateInstance(_type);
          foreach (PropertyInfo prop in _type.GetProperties())
          {
              if (prop.CanWrite)
              {
                  if (prop.Name == "ID")
                  {
                      ctrlDest.ID = ctrlSource.ID + "_copy_" + _controlCount;
                  }
                  else
                  {
                      prop.SetValue(ctrlDest, prop.GetValue(ctrlSource, null), null);
                  }
              }
          }
          _controlCount++;
  
          return ctrlDest;
      }
      public void InstantiateIn(Control container)
      {
          switch (_templateType)
          {
              case ListItemType.Header:
                  container.Controls.Add(_control);
                  break;
              case ListItemType.Item:
                  Control temp = Copy(_control);
                  if(_bindHandler != null)
                      temp.DataBinding += _bindHandler;
                  if (_initHandler != null)
                      temp.Init += _initHandler;
                  container.Controls.Add(temp);
                  break;
          }
      }
  
  }
  </code></pre>
  
  <p>In the page that needs say Default.aspx.cs, I create this gridview onPreInit and attach its event handlers onInit. </p>
  
  <p>I add a checkbox to the grid by calling the addTemplateField().</p>
  
  <pre><code>cbl = new CheckBox();
  cbl.AutoPostBack = true;
  init = new EventHandler(cbl_Init);
  grd.addTemplateField(null, cbl, null, init, "SERVER", null, true, 20, 20);
  
  void cbl_Init(object sender, EventArgs e)
  {
      CheckBox c = (CheckBox)sender;
      c.CheckedChanged +=new EventHandler(cbl_CheckedChanged);
  }
  
  void cbl_CheckedChanged(object sender, EventArgs e)
  {
    // Modify datasource
    // databind();
  </code></pre>
  
  <p>// if i remove this databind, checkchanged is handled every time. If i keep the databind, event is handled only alternate times.
      }</p>
  
  <p>The issue is the checkbox checkchanged event is fired for alternate times. Every other time, the page post backs but the checkchanged event is not handled. I am lost in finding the cause, let alone the solution.!?!?!</p>