title: ASP.NET Modifying Control Tree Dynamically
body: <p>I am trying to drop and add controls dynamically to my control tree. For example:</p>
  
  <p>Under a specific condition, I am calling:</p>
  
  <pre><code>    private void resetPanel()
      {
          Panel.Controls.Clear();
          Panel.Controls.Add(Image);
          Panel.Controls.Add(HiddenField);
      }
  </code></pre>
  
  <p>My main objective is how do I get the added controls to persist across postbacks?</p>
  
  <p>When I call another similar function using textboxes and titles, it persists perfectly. However, with the image it loses its URL and properties.</p>
  
  <p>I understand that for dynamic controls to persist, you must add it on the Init, and you must be responsible for the control tree thus needing to add the dynamic control to the tree on every postback.</p>
  
  <p>So why does it work for textboxes and labels persisting across post backs but you cannot do the control add for images and hiddenfields?</p>
  
  <p>Thanks,
  Brian</p>
  
  <p><strong>--Update and Solution--</strong></p>
  
  <p>I have found a mistake in my code, and the HiddenField values do persist across post backs. The solution I have opted for is to use the ViewState to save the values, then restore my dynamic controls on each post back.</p>
  
  <p><strong>--Edit--</strong></p>
  
  <p>Thank you for the replies, and since there may be a better solution to my problem, here is some code that will hopefully show how I am calling the method and why I would need to.</p>
  
  <pre><code>    public void resetTitlePanel()
      {
          // Restylize the panel to initial state
          TitlePanel.Controls.Clear();
          TitlePanel.BorderColor = System.Drawing.Color.Maroon;
          TitlePanel.BorderStyle = BorderStyle.Dashed;
          TitlePanel.Enabled = true;
  
          // Set the new control properties to initial state
          Label TitleLabel = new Label();
          TitleLabel.ID = "TitleLabel";
  
          TextBox TitleTxtBox = new TextBox();
          TitleTxtBox.ID = "TitleTxtBox";
  
          // Add the new controls to the container
          TitlePanel.Controls.Add(TitleLabel);
          TitlePanel.Controls.Add(TitleTxtBox);
  
          // Set the reference of this to the new dynamic control
          this.TitleLabel = TitleLabel;
          this.TitleTxtBox = TitleTxtBox;
      }
  
      public void resetImagePanel()
      {
          // Restylize the panel to initial state
          ImagePanel.Controls.Clear();
          ImagePanel.BorderColor = System.Drawing.Color.Blue;
          ImagePanel.BorderStyle = BorderStyle.Dashed;
          ImagePanel.HorizontalAlign = HorizontalAlign.NotSet;
  
          // Set the new control properties to initial state
          Image AddImage = new Image();
          AddImage.ImageUrl = "~/Resources/Icons/picture_add.png";
          AddImage.ID = "AddImage";
  
          HiddenField HiddenImage = new HiddenField();
          HiddenImage.ID = "HiddenImage";
  
          // Add the new controls to the container
          ImagePanel.Controls.Add(AddImage);
          ImagePanel.Controls.Add(HiddenImage);
  
          // Set the reference of this to the new dynamic control
          this.AddImage = AddImage;
          this.HiddenImage = HiddenImage;
      }
  </code></pre>
  
  <p>The Calling Method:</p>
  
  <pre><code>private void copyFromSlide(TemplateControl destination, Template source)
      {
          // Reset the template
          destination.resetTitlePanel();
          destination.resetImagePanel();
  
          destination.Title = source.Title;
          // Find the path from the database and assign it to the control
          destination.ImagePath = modData.getImagePath((int)source.ImageID);
      }
  </code></pre>
  
  <p>So... I understand that the code is complex, perhaps more than it should be. Further, I am just a beginner so it may be of worse quality, and I apologize for that.</p>
  
  <p>Key notes are:</p>
  
  <ul>
  <li>There are 2 user controls that are interacting with each other.</li>
  <li>This works completely fine on !IsPostback.</li>
  <li>The ViewStateEnable is true on default, even if I assign it true explicitly, I get the same results.</li>
  <li>This works completely for the title panel which consists of a label and textbox, both of which retains its value.</li>
  <li>I know I am mixing static and dynamic controls together. I am used to C, so I am unsure if I could just move the object pointer to the new dynamic object.</li>
  </ul>
  
  <p>The problem is, when assigning the image path, the value does not retain on postback.</p>
  
  <p>I need to drop and re-add controls because under specific conditions I will drop the controls and add labels, which as noted, have no problem. The reason why I believe that I do not need to initialize the controls over again is because I am adding to a rooted panel as demonstrated by:</p>
  
  <p><a href="http://weblogs.asp.net/infinitiesloop/archive/2006/08/30/TRULY-Understanding-Dynamic-Controls-_2800_Part-3_2900_.aspx" rel="nofollow">http://weblogs.asp.net/infinitiesloop/archive/2006/08/30/TRULY-Understanding-Dynamic-Controls-_2800_Part-3_2900_.aspx</a></p>
  
  <p>I hope this adds some clarity.</p>
  
  <p>Thanks once again,</p>
  
  <p>-Brian</p>