title: Asp.net Dynamically recreating ListBoxes on PostBack
body: <p>I want to create dynamically added <code>ListBoxes</code> based on Main Categories and Subcategories where they can be an infinite amount of sub categories. I have been working on this all week and can't figure this out.</p>
  
  <p>I want it to be like Ebay category selection. When the page loads there will be a listbox with all the main categories. When a user selects an item in the listbox, another listbox should be added dynamically such that each listbox has the selected item still there. So after selected the first item in the first listbox there should be two listboxes with the second listbox showing all subcategories that belong to the one selected. Please see screenshot.</p>
  
  <p><a href="http://www.aquariumbids.com/Images/ebayCat.JPG" rel="nofollow noreferrer">Ebay Category Selection Example http://www.aquariumbids.com/Images/ebayCat.JPG</a></p>
  
  <p><strong>CODE PER REQUEST</strong> 
  - Its close to working I think.</p>
  
  <pre><code>    public partial class WebForm2 : System.Web.UI.Page
  {
      private Int32 controlCount = 0;
      Panel _panel;
  
      private Panel PanelPlaceholder
      {
          get
          {
              if (_panel == null &amp;&amp; Master != null)
                  _panel = pnlContainer;
              return _panel;
          }
      }
  
      protected void Page_PreInit(Object sender, EventArgs e)
      {
          this.EnsureChildControls();
  
          if (IsPostBack)
          {
              // Re-create controls but not from datasource
              // The controlCount value is output in the page as a hidden field during PreRender.
              controlCount = Int32.Parse(Request.Form["controlCount"]); // assigns control count from persistence medium (hidden field)         
              for (Int32 i = 0; i &lt; controlCount; i++)
              {
                  CreateDynamicControlGroup(false);
              }
          }
      }
      protected void Page_Load(Object sender, EventArgs e)
      {
          // create from data query.
          // only if not postback
          if (!IsPostBack)
          {
              int cc = controlCount;
  
              DataTable dt = null;                
              Dictionary&lt;string, string&gt; Params = new Dictionary&lt;string, string&gt;();
              dt = Globals.g_DatabaseHandler.GetRecords(StoredProcedures.GetMainCategories, Params);
  
              // create a set of dynamic controls for the Row, incrementing counter and 
              // getting a reference to the new controls via their common parent (Dynamic PlaceHolder)
              CreateDynamicControlGroup(true);
  
              ListBox lb = (ListBox)PanelPlaceholder.Controls[controlCount - 1];
  
              // On reload you will see that child ListItems are persisted by the DropDownList
              lb.DataSource = dt; // use the same table
              lb.DataValueField = "ID";
              lb.DataTextField = "Name";
              lb.DataBind();
          }
      }
  
  
      protected void Page_PreRender(Object sender, EventArgs e)
      {
          // persist control count
          ClientScript.RegisterHiddenField("controlCount", controlCount.ToString());
      }
  
  
      private void ListBox_SelectedIndexChanged(Object sender, EventArgs e)
      {
          ListBox lb = sender as ListBox;
  
  
          Dictionary&lt;string, string&gt; Params = new Dictionary&lt;string, string&gt;();
          Params.Add("parentID", lb.SelectedValue);
          DataTable Categories = Globals.g_DatabaseHandler.GetRecords(StoredProcedures.GetChildCategories, Params);
  
          if (Categories.Rows.Count &gt; 0)
          {
              // create a set of dynamic controls for the Row, incrementing counter and 
              // getting a reference to the new controls via their common parent (Dynamic PlaceHolder)
              CreateDynamicControlGroup(true);
  
              ListBox newLb = (ListBox)PanelPlaceholder.Controls[controlCount - 1];
              // On reload you will see that child ListItems are persisted by the DropDownList
              newLb.DataSource = Categories; // use the same table
              newLb.DataValueField = "ID";
              newLb.DataTextField = "Name";
              newLb.DataBind();
          }
      }
  
  
      private void CreateDynamicControlGroup(Boolean incrementCounter)
      {
          // Create one logical set of controls do not assign values!
          ListBox lb = new ListBox();
          lb.AutoPostBack = true;
          lb.CssClass = "panel";
          PanelPlaceholder.Controls.Add(lb);
  
          // wire event delegate
          lb.SelectedIndexChanged += new EventHandler(ListBox_SelectedIndexChanged);
  
          if (incrementCounter)
          {
              controlCount += 1;
          }
      }
  }  
  </code></pre>
  
  <p>Markup:</p>
  
  <pre><code> &lt;div class="Column12" id="Form_NewListing"&gt;
      &lt;h2 class="h2row"&gt;Create Your Listing - Step 1 of 2)&lt;/h2&gt;
      &lt;h3 class="h3row"&gt;Select a category&lt;/h3&gt;
      &lt;div class="panel"&gt;
          &lt;asp:Panel ID="pnlContainer" runat="server"&gt;&lt;/asp:Panel&gt;        
  
      &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>