Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Dynamically created controls lose state on postback

Posted on 2014-03-28
4
Medium Priority
?
1,052 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

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

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

ASP.Net to Oracle Connectivity Recently I had to develop an ASP.NET application connecting to an Oracle database.As I am doing it first time ,I had to solve several problems. This article will help to such developers  to develop an ASP.NET client…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
this video summaries big data hadoop online training demo (http://onlineitguru.com/big-data-hadoop-online-training-placement.html) , and covers basics in big data hadoop .
Screencast - Getting to Know the Pipeline
Suggested Courses

876 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