Dynamically created controls lose state on postback

My dynamically created controls are losing state.

Here is the process...

1 PageLoads
2 On DDLSelectedIndexChanged controls are created dynamically
3 On ButtonClick I want to read the values from the controls but they are gone

This makes sense but I'm not sure how to address it. Below is a code sample I wrote that exposes the problem I'm running in to. Just try to run it and you will see what I mean.

<%@ Page Language="C#" %>

<!DOCTYPE html>

<script runat="server">


    protected void Page_Load(object sender, EventArgs e)
    {
        ButtonSubmit.Visible = false;    
    }
    
    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (DropDownList1.SelectedIndex == 0)
            return;
        
        FillTableControls();
        ButtonSubmit.Visible = true;
    }

    protected void FillTableControls()
    {
        AddTextBoxRow("1", "Name");
        AddTextBoxRow("2", "Address");
        AddTextBoxRow("3", "Email");
    }

    protected void AddTextBoxRow(string suffix, string labelText)
    {
        TableRow row = new TableRow();
        TableCell cell1 = new TableCell();
        TableCell cell2 = new TableCell();

        System.Web.UI.WebControls.Label label = new System.Web.UI.WebControls.Label();
        System.Web.UI.WebControls.TextBox textbox = new System.Web.UI.WebControls.TextBox();

        label.ID = "Label" + suffix;
        label.Text = labelText;
        textbox.ID = "TextBox" + suffix;
        cell1.Width = 200;
        cell1.Controls.Add(label);
        cell2.Controls.Add(textbox);
        row.Cells.Add(cell1);
        row.Cells.Add(cell2);

        TableControls.Rows.Add(row);
    }


    protected void ButtonSubmit_Click(object sender, EventArgs e)
    {
        for (int i = 1; i < 4; i++)
        {
            string controlName = "TextBox" + i.ToString();
            TextBox t = (TextBox)this.TableControls.FindControl(controlName);
            LabelMessage.Text += t.Text + ", ";
        }
    }
    
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
        <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" >
            <asp:ListItem>Select something...</asp:ListItem>
            <asp:ListItem>This will do</asp:ListItem>
        </asp:DropDownList>
        <br />
        <br />
        <asp:Table ID="TableControls" runat="server">
        </asp:Table>
        <br />
        <asp:Button ID="ButtonSubmit" runat="server" Text="Postback" OnClick="ButtonSubmit_Click"  />
    
        <br />
        <br />
        <asp:Label ID="LabelMessage" runat="server"></asp:Label>
    
    </div>
    </form>
</body>
</html>

Open in new window

LVL 1
tatton777Asked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
tatton777Connect With a Mentor Author Commented:
I ended up getting help elsewhere. You have to load the table with the controls on EVERY POSTBACK once the set of controls is instantiated. You can do this on the Page_Load or the Page_Init, it doesn't matter.

    //==================================================
    // Page_Load()
    //==================================================
    protected void Page_Load(object sender, EventArgs e)
    {
        if(!Page.IsPostBack)
        {

        }
        if(sv.FillPdfPageFormControls != null)
            LoadTableWithPdfControls(sv.FillPdfPageFormControls);
    }

    //==================================================
    // LoadTableWithPdfControls()
    //==================================================
    protected void LoadTableWithPdfControls(DataTable formContols)
    {
        int rowCount = 1;

        foreach (DataRow r in formContols.Rows)
        {
            string controlType = r["ControlType"].ToString().ToLower().Trim();

            if (controlType == "spacer")
            {
                TableRow row = new TableRow();
                TableCell cell = new TableCell();
                cell.ColumnSpan = 2;
                cell.Text = " ";
                row.Cells.Add(cell);                
                
                TableControls.Rows.Add(row);
                TableControls.Rows.Add(row);
            }

            if (controlType == "label")
            {
                TableRow row = new TableRow();
                TableCell cell = new TableCell();

                System.Web.UI.WebControls.Label label = new System.Web.UI.WebControls.Label();
                label.Text = r["ControlText"].ToString();
                label.ID = r["ControlName"].ToString();
                cell.ColumnSpan = 2;
                cell.Controls.Add(label);
                row.Cells.Add(cell);
                TableControls.Rows.Add(row);
            }

            if (controlType == "textbox")
            {
                TableRow row = new TableRow();
                TableCell cell1 = new TableCell();
                TableCell cell2 = new TableCell();

                System.Web.UI.WebControls.Label label = new System.Web.UI.WebControls.Label();
                System.Web.UI.WebControls.TextBox textbox = new System.Web.UI.WebControls.TextBox();
                label.ID = "Label" + rowCount.ToString();
                label.Text = r["ControlText"].ToString();

                //TextBox wk = (TextBox)this.TableControls.FindControl(r["controlName"].ToString());

                textbox.ID = r["ControlName"].ToString();

                cell1.Width = 200;
                cell1.Controls.Add(label);
                cell2.Controls.Add(textbox);
                row.Cells.Add(cell1);
                row.Cells.Add(cell2);

                TableControls.Rows.Add(row);
            }

            if (controlType == "checkbox")
            {
                TableRow row = new TableRow();
                TableCell cell1 = new TableCell();
                TableCell cell2 = new TableCell();

                System.Web.UI.WebControls.CheckBox checkbox = new System.Web.UI.WebControls.CheckBox();

                checkbox.Text = r["ControlText"].ToString();
                checkbox.ID = r["ControlName"].ToString();

                cell2.Controls.Add(checkbox);
                row.Cells.Add(cell1);
                row.Cells.Add(cell2);
                TableControls.Rows.Add(row);
            }
            rowCount += 1;
        }
    }

Open in new window

0
 
Dale BurrellDirectorCommented:
I think you have to recreate the control tree that was sent to the browsers earlier in the event chain. I think you have to create it on postback during the onload event at the latest for the ASP.NET framework to load viewstate data for the controls etc.

Then you can modify the control tree again later in your onclick event.
0
 
GowthamNatarajanCommented:
Try this...
Creating a static table and binding it to panel helps....

<%@ Page Language="C#" %>
<!DOCTYPE html>
<script runat="server">


    static Table tab = new Table();

    protected void Page_Load(object sender, EventArgs e)
    {
        ButtonSubmit.Visible = false;
        if (IsPostBack)
        {
         pan.Controls.Add(tab);
        }
        else
        {
            pan.Controls.Remove(tab);
        }
    }

    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (DropDownList1.SelectedIndex == 0)
            return;

        FillTableControls();
        ButtonSubmit.Visible = true;
    }

    protected void FillTableControls()
    {
        AddTextBoxRow("1", "Name");
        AddTextBoxRow("2", "Address");
        AddTextBoxRow("3", "Email");
    }

    protected void AddTextBoxRow(string suffix, string labelText)
    {
        TableRow row = new TableRow();

        TableCell cell1 = new TableCell();
        TableCell cell2 = new TableCell();
        System.Web.UI.WebControls.Label label = new System.Web.UI.WebControls.Label();
        System.Web.UI.WebControls.TextBox textbox = new System.Web.UI.WebControls.TextBox();

        label.ID = "Label" + suffix;
        label.Text = labelText;
        textbox.ID = "TextBox" + suffix;
        cell1.Width = 200;
        cell1.Controls.Add(label);
        cell2.Controls.Add(textbox);
        row.Cells.Add(cell1);
        row.Cells.Add(cell2);

        tab.Rows.Add(row);

        pan.Controls.Add(tab);
    }

    protected void ButtonSubmit_Click(object sender, EventArgs e)
    {
        for (int i = 1; i < 4; i++)
        {
            string controlName = "TextBox" + i.ToString();
            TextBox t = (TextBox)FindControl(controlName);
            LabelMessage.Text += t.Text + ", ";
        }
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
   
        <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" >
            <asp:ListItem>Select something...</asp:ListItem>
            <asp:ListItem>This will do</asp:ListItem>
        </asp:DropDownList>
        <br />
        <br />
        <asp:Panel ID="pan" runat="server"></asp:Panel>
        <br />
        <asp:Button ID="ButtonSubmit" runat="server" Text="Postback" OnClick="ButtonSubmit_Click"  />
   
        <br />
        <br />
        <asp:Label ID="LabelMessage" runat="server"></asp:Label>
   
    </div>
    </form>
   </body>
</html>
0
 
tatton777Author Commented:
Hello,
This question is almost exactly the same as the other that I answered. It required the same answer.

I found the answer to my question somewhere besides EE and decided to share it with the community.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.