Solved

Dynamically created controls lose state on postback

Posted on 2014-03-28
4
876 Views
Last Modified: 2014-04-29
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

0
Comment
Question by:tatton777
  • 2
4 Comments
 
LVL 21

Expert Comment

by:Dale Burrell
ID: 39963210
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
 
LVL 2

Expert Comment

by:GowthamNatarajan
ID: 39963257
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
 
LVL 1

Accepted Solution

by:
tatton777 earned 0 total points
ID: 40020952
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
 
LVL 1

Author Closing Comment

by:tatton777
ID: 40029070
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

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article shows how to use the open source plupload control to upload multiple images. The images are resized on the client side before uploading and the upload is done in chunks. Background I had to provide a way for user…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
Hi friends,  in this video  I'll show you how new windows 10 user can learn the using of windows 10. Thank you.

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

25 Experts available now in Live!

Get 1:1 Help Now