title: How to Add/Delete Dynamically Created User Controls
body: <p>So I'm trying to add and delete user controls on a page dynamically, by elaborating on an example I found online which shows how to add user controls dynamically. But I cannot seem to get the removal working properly. Procedure I follow is roughly.....</p>
  
  <ul>
  <li><p>In the main page, when the add button is clicked, I create a user control and assign its <code>deleteBtnClk</code> event instance to method <code>deleteBtn_Click(object sender, EventArgs e)</code>, which I pass method <code>ucSimpleControl_deleteBtnClk</code> from the main page code behind</p>
  
  <pre><code>protected void btnAddControl_Click(object sender, EventArgs e)
  {
      // Create instance of the UserControl SimpleControl
      usercontrols.SimpleControl ucSimpleControl =
        LoadControl("~/usercontrols/SimpleControl.ascx")
        as usercontrols.SimpleControl;
  </code></pre>
  
  <p>...
  ...
  ...</p>
  
  <pre><code>    ucSimpleControl.deleteBtnClk +=
          new usercontrols.deleteBtn_Click(ucSimpleControl_deleteBtnClk);
  </code></pre></li>
  </ul>
  
  <p>I also do this is code behind method <code>CreateUserControl(string controlID)</code>, which is called from the <code>OnPreInit</code> method...</p>
  
  <pre><code>  protected override void OnPreInit(EventArgs e)
          {
    ...
    ...
    ...
          if ((control != null &amp;&amp; control.ClientID ==
                          btnAddControl.ClientID) || createAgain)
          {
          ...
          ...
          ...
  
              CreateUserControl(controlID);
          }
  </code></pre>
  
  <p>The OnClick method for the remove button in my user controls is set to deleteBtn_Click</p>
  
  <pre><code>  protected void deleteBtn_Click(object sender, EventArgs e)
      {
          onDelBtnClk(e);
      }
  </code></pre>
  
  <p>which calls the virtual method onDelBtnClk</p>
  
  <pre><code>   protected virtual void onDelBtnClk(EventArgs e)
          {
              deleteBtnClk(this, e);
          }
  </code></pre>
  
  <p>and passes this and the eventargs to the delegate, which on user control creation and rendering was assigned to code behind method ucSimpleControl_deleteBtnClk</p>
  
  <pre><code> void ucSimpleControl_deleteBtnClk(object sender, EventArgs e)
          {
              usercontrols.SimpleControl ucSimpleControl =
                  ((usercontrols.SimpleControl)(sender));
              ucSimpleControl.Parent.Controls.Remove(ucSimpleControl);
              Session.Remove((ucSimpleControl.Num).ToString());
              CreateUserControl(controlID);
          }
  </code></pre>
  
  <p>In here I attempt to remove the user  control by getting the parent control and invoking the Controls.Remove method with the sender user control as the argument. Then I remove the key-value pair associated with the user control from the Session, and finally call CreateUserControl again to render all user controls in Session. But the behavior is strange, only the most recently created user control is removed, not the one associated with the remove button clicked, and also after I remove one user control I cannot add more than the number of user controls that exist at that moment to the page. Like, for example, if there are 5 user controls on the page, and I remove one, then try to add more, I wont be able to add more than 5, though I should be able to add infinitely many. Here is the full source...</p>
  
  <p>DisplayPage.aspx.cs</p>
  
  <pre><code>namespace UserControls4
  {
      public partial class DisplayPage : System.Web.UI.Page
      {
      protected void Page_Load(object sender, EventArgs e)
      {
  
      }
  
      protected void btnAddControl_Click(object sender, EventArgs e)
      {
          // Create instance of the UserControl SimpleControl
          usercontrols.SimpleControl ucSimpleControl =
            LoadControl("~/usercontrols/SimpleControl.ascx")
            as usercontrols.SimpleControl;
  
          // Set the Public Properties
          ucSimpleControl.FirstName.Text = "Milind";
          ucSimpleControl.LastName.Text = "Chavan";
  
          //Create Event Handler for btnPost Click 
          ucSimpleControl.btnPostClk +=
                  new usercontrols.btnPost_Click(ucSimpleControl_btnPostClk);
          /////////////////////////////////////////////////////////////////////////////////////////////////////////////
          ucSimpleControl.deleteBtnClk +=
              new usercontrols.deleteBtn_Click(ucSimpleControl_deleteBtnClk);
          /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
          //Add the SimpleControl to Placeholder
          Placeholder1.Controls.Add(ucSimpleControl);
  
          // Add the instance of the SimpleControl to Session Variable
          Session.Add((Session.Count + 1).ToString(), ucSimpleControl);
  
          // Set createAgain = true
          createAgain = true;
      }
  
      void ucSimpleControl_btnPostClk(object sender, EventArgs e)
      {
          usercontrols.SimpleControl ucSimpleControl =
                      ((usercontrols.SimpleControl)(sender));
          lblUser.Text = "Welcome " + ucSimpleControl.FirstName.Text +
                         " " + ucSimpleControl.LastName.Text;
      }
  
      ///////////////////////////////////////////////////////////////////////////////////////////////////////
      void ucSimpleControl_deleteBtnClk(object sender, EventArgs e)
      {
          usercontrols.SimpleControl ucSimpleControl =
              ((usercontrols.SimpleControl)(sender));
          ucSimpleControl.Parent.Controls.Remove(ucSimpleControl);
          Session.Remove((ucSimpleControl.Num).ToString());
          CreateUserControl(controlID);
      }
      ////////////////////////////////////////////////////////////////////////////////////////////////////////
  
      // Declare 2 variable to handle user control after postback
      const string controlID = "MyUserControl";
      static bool createAgain = false;
  
      protected Control GetPostBackControl(Page page)
      {
          Control control = null;
          try
          {
              string ctrlName = page.Request.Params.Get("__EVENTTARGET");
  
              if (ctrlName != null &amp;&amp; ctrlName != String.Empty)
              {
                  control = page.FindControl(ctrlName);
              }
              else
              {
                  ContentPlaceHolder cph =
                    (ContentPlaceHolder)page.FindControl("Main");
                  for (int i = 0, len = page.Request.Form.Count; i &lt; len; i++)
                  {
                      string[] ctl = page.Request.Form.AllKeys[i].Split('$');
                      if (ctl.Length &gt; 3)
                      {
                          control = cph.FindControl(ctl[2])
                                    as System.Web.UI.WebControls.Button;
                      }
  
                      if (control != null) break;
                  }
              }
          }
          catch (Exception ex)
          {
              throw ex;
          }
          return control;
      }
  
      protected override void OnPreInit(EventArgs e)
      {
          base.OnPreInit(e);
  
          Control control = GetPostBackControl(this.Page);
  
          // Check if the postback is caused by the button 
          // Titled "Click to Create a Dynamic Control"
          // OR
          // createAgain field is true 
          // which means a call is made to the server while the 
          // user control is active  
  
          if ((control != null &amp;&amp; control.ClientID ==
                          btnAddControl.ClientID) || createAgain)
          {
              //should be set before the CreateUserControl method
              createAgain = true;
  
              CreateUserControl(controlID);
          }
      }
  
      protected void CreateUserControl(string controlID)
      {
          // createAgain field is set to true in the OnPreInit method
          // when the 'Create User Control' button is clicked 
  
          // the createAgain field is used to check if the
          // user control is on the page before the call 
          // if so create the control again and add it to the
          // Control Hierarchy again
          try
          {
              if (createAgain &amp;&amp; Placeholder1 != null)
              {
                  if (Session.Count &gt; 0)
                  {
                      Placeholder1.Controls.Clear();
                      int simpleControlCount = 0;
                      for (int i = 0; i &lt; Session.Count; i++)
                      {
                          switch (Session[i].ToString())
                          {
                              case "ASP.usercontrols_simplecontrol_ascx":
                                  {
                                      // Keep count of all SimpleControls
                                      simpleControlCount++;
                                      // Create instance of the UserControl SimpleControl
                                      usercontrols.SimpleControl ucSimpleControl =
                                        LoadControl("~/usercontrols/SimpleControl.ascx")
                                        as usercontrols.SimpleControl;
  
                                      // Set the Public Properties
                                      ucSimpleControl.FirstName.Text =
                                        ((usercontrols.SimpleControl)(Session[i])).FirstName.Text;
                                      ucSimpleControl.LastName.Text =
                                        ((usercontrols.SimpleControl)(Session[i])).LastName.Text;
                                      ucSimpleControl.Num = simpleControlCount;
  
                                      //Create Event Handler for btnPost Click 
                                      ucSimpleControl.btnPostClk +=
                                        new usercontrols.btnPost_Click(ucSimpleControl_btnPostClk);
  
                                      /////////////////////////////////////////////////////////////////////////////////////////////////////////
                                      ucSimpleControl.deleteBtnClk +=
                                           new usercontrols.deleteBtn_Click(ucSimpleControl_deleteBtnClk);
                                      //////////////////////////////////////////////////////////////////////////////////////////////////////////
  
                                      //Add the SimpleControl to Placeholder
                                      Placeholder1.Controls.Add(ucSimpleControl);
                                      break;
                                  }
                          }
                      }
                  }
              }
          }
          catch (Exception ex)
          {
              throw ex;
          }
      }
  
  }
  </code></pre>
  
  <p>}</p>
  
  <p>DisplayPage.aspx</p>
  
  <pre><code>&lt;head id="Head1" runat="server"&gt;
      &lt;title&gt;This is example of how to add usercontrol dynamically&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
      &lt;form id="form1" runat="server"&gt;
      &lt;div&gt;
              &lt;asp:Button ID="btnAddControl" runat="server" 
                Text="Click to add SimpleControl" 
                onclick="btnAddControl_Click" /&gt;
              &lt;br /&gt;
              &lt;asp:PlaceHolder runat="server" 
             ID="Placeholder1" &gt;&lt;/asp:PlaceHolder&gt;
              &lt;br /&gt;
              &lt;asp:Label ID="lblUser" 
                runat="server"&gt;&lt;/asp:Label&gt;
      &lt;/div&gt;
      &lt;/form&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>SimpleControl.ascx.cs</p>
  
  <pre><code>namespace UserControls4.usercontrols
  {
      public delegate void btnPost_Click(object sender, System.EventArgs e);
      public delegate void deleteBtn_Click(object sendre, System.EventArgs e);
  
      public partial class SimpleControl : System.Web.UI.UserControl
      {
          protected void Page_Load(object sender, EventArgs e)
          {
  
          }
  
          private int num;
  
          #region Public Event
  
          public event btnPost_Click btnPostClk;
          public event deleteBtn_Click deleteBtnClk;
  
          #endregion
  
          #region Public Properties
  
          public TextBox FirstName
          {
              get
              {
                  return txtFirstName;
              }
              set
              {
                  txtFirstName = value;
              }
          }
  
          public TextBox LastName
          {
              get
              {
                  return txtLastName;
              }
              set
              {
                  txtLastName = value;
              }
          }
  
          public int Num
          {
              get { return this.num; }
              set { this.num = value; }
          }
          #endregion
  
          #region Vitual Methods
  
          protected virtual void OnbtnDelQtnMrClk(EventArgs e)
          {
              // Call btnPost_Click event delegate instance
              btnPostClk(this, e);
          }
  
          /// ///////////////////////////////////////////////////////////////////////////////////////
          protected virtual void onDelBtnClk(EventArgs e)
          {
              deleteBtnClk(this, e);
          }
  
          /// /////////////////////////////////////////////////////////////////////////////////////////
  
          #endregion
  
          protected void btnPost_Click(object sender, EventArgs e)
          {
              //Call Virtual Method
              OnbtnDelQtnMrClk(e);
          }
  
          ///////////////////////////////////////////////////////////////////////////////////////////
          protected void deleteBtn_Click(object sender, EventArgs e)
          {
              onDelBtnClk(e);
          }
  
      }
  }
  </code></pre>
  
  <p>SimpleControl.ascx</p>
  
  <pre><code>&lt;table&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;asp:Label ID="label1" runat="server" 
              Text="First Name" &gt;&lt;/asp:Label&gt;&lt;/td&gt;
          &lt;td&gt; &lt;asp:TextBox ID="txtFirstName" 
              runat="server"&gt;&lt;/asp:TextBox&gt;&lt;/td&gt;
      &lt;/tr&gt;
       &lt;tr&gt;
          &lt;td&gt;&lt;asp:Label ID="label2" runat="server" 
             Text="Last Name" &gt;&lt;/asp:Label&gt;&lt;/td&gt;
          &lt;td&gt; &lt;asp:TextBox ID="txtLastName" 
             runat="server"&gt;&lt;/asp:TextBox&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;asp:Button ID="btnPost"  runat="server" 
              Text="Send Info" OnClick="btnPost_Click" /&gt;
          &lt;/td&gt;
      &lt;/tr&gt;
  &lt;/table&gt;
  &lt;obout:SuperForm ID="UserControlSuperForm" 
      Width="630" Title="SuperForm"
      AutoGenerateRows="false"
      RunAt="server"
      DefaultMode="Insert"
      FolderStyle="styles/black_glass"&gt;
      &lt;Fields&gt;
          &lt;obout:TemplateField HeaderText="SuperForm"&gt;
              &lt;EditItemTemplate&gt;
                  &lt;asp:TextBox ID="superFormTxt" runat="server"&gt;&lt;/asp:TextBox&gt;
              &lt;/EditItemTemplate&gt;
          &lt;/obout:TemplateField&gt;
      &lt;/Fields&gt;
  &lt;/obout:SuperForm&gt;
  &lt;asp:Button ID="removeBtn" runat="server" Text="Remove" OnClick="deleteBtn_Click"/&gt;
  </code></pre>