Tucker
Tucker

Reputation: 188

Accessing dynamically added controls on postback

I'm trying to get the dynamic Control that caused a postback. All Controls are added dynamically to a Panel.

<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
    <asp:Panel runat="server" ID="panel"></asp:Panel>
</asp:Content>

I have read that the two following methods should find the postback Control (at this point I am not concerned with Buttons causing a postback, but will be).

private Control GetPostBackControl()
            {
            Control toReturn = null;
            string controlName = page.Request.Params.Get("__EVENTTARGET");
            if (!String.IsNullOrEmpty(controlName))
            {
                toReturn = RecurseControls(this.Page, controlName);
            }
           return toReturn;
    }

 private Control RecurseControls(Control root, String toFind)
        {
            String s = root.UniqueID;
            if (root.UniqueID == toFind)
            {
                return root;
            }
            foreach (Control c in root.Controls)
            {
                Control t = RecurseControls(c, toFind);
                if (t != null)
                {
                    return t;
                }
            }
            return null;
        }

When stepping through the debugger, the recursion finds the panel, but there are no child Controls within it. I'm assuming that my understanding of how these methods work was initially off, and they cannot find dynamically added Controls before they are recreated for this Post. If this is the case, is there another way to find the dynamic Control that triggered the postback? If not, is there a way to cause the page to re-post within a Control's EventHandler?

Please note that I am using a master page. Whether I use the recursive method as I have posted it, or like RecurseControls(this.Master, toFind); I still don't see the Panel's child Controls. GetPostBackControl() is also called within Page_Init().

Upvotes: 2

Views: 3386

Answers (2)

andleer
andleer

Reputation: 22568

In general, dynamically added controls will need to be re-added on each server round trip. The exception are control content of controls that maintain ViewState. Insure that your controls are added during PageInit which occurs before ViewState is loaded.

Then you can simply reference your controls to acquire their contents, values, selected indexes etc.

Upvotes: 3

Icarus
Icarus

Reputation: 63956

If you just need to find the values entered on any of the controls added dynamically, you can always find those values by simply accessing the Request.Params collection. For example, if you dynamically add an TextBox control with name "MyTextBox", when the page posts back, regardless of how the control was added, the Request.Params["MyTextBox"] will have the value inputted by the user; again, provided you assign a name to the control.

Quick example:

TextBox b= null;
for (int i = 0; i < 4; i++)
{
      b=new TextBox();
      b.ID="textbox"+i;
      //asp.net will assign the name the same as the ID of the element
      placeHolder.Controls.Add(b); //placeHolder is the container for all dynamically-added controls
}

When the page posts back, you can get, for example, the value entered on "textbox1" as so:

if (IsPostBack)
{
    Response.Write(Request.Params["textbox1"]);
}

Finally, iterating recursively to find a control is incredibly inefficient. The performance degrades exponentially as more controls are added to the page. With care, one can almost always find a control in O(1) or at least O(n) if you structure your page carefully and instead of searching through the whole page, you only search through the parent container.

Upvotes: 1

Related Questions