简体   繁体   中英

Insert dynamic controls after page_load (ViewState persistent)

I have a page where I create a dynamic table, containing dynamic controls which raise events. It works, but I wan't to re-generate that table in some events (so after page_load) to print table modifications.

I understand the problem, its that at this moment, my controls aren't persisted in the viewstate because they are created after page_load, and their events are not raised. But how could I do this ?

Here is my code:

protected void Page_Load(object sender, EventArgs e)
{
    generateTable(); // When pass just here, it works well
}

private void generateTable()
{
    Table tbl = new Table();
    // Here I create my table with controls

    tableContainer.Controls.Clear(); // tableContainer is a Panel fixed in aspx page
    tableContainer.Controls.Add(tbl);
}

protected void txt_TextChanged(object sender, EventArgs e)
{
    // Do some stuff to change values in the table
    generateTable(); // Re-generate (but events will not be raised)
}

UPDATE 1:

I thought about something (which complicate my development), but I should do generateTable which creates all my lines and controls and call it on each page_load. And in the other hand create another method which populate controls ? So in events, I call the second one.

But my table is generated dynamically, and controls can also be added after an event (I have a dropdownlist which create a new line and control in the table, so I'm stuck also here cause I won't see the line at the first postback ?)

Here is a really good link that describes management of dynamically added controls: https://web.archive.org/web/20050321094957/http://devcenter.infragistics.com/Articles/ArticleTemplate.ASPX?ArticleID=2149

Note that once you add the control in your ASP.NET backend anywhere, you have to set property

ViewState["AddedControl"] = "true";

Also, during postback, your page will be regenerated so at that time you will have to re-create the control and set old values backs.

From the same link:

public void Page_Load() {
   if (IsPostBack) {
      if (ViewState["AddedControl"] != null) {
         // Re-create the control but do not
         // restore settings configured outside
         // the proc (i.e., MaxLength and BackColor)
         TextBox t = AddTextBox(); 
      }  
   }
}
public void OnClick(object sender, EventArgs e) {
   TextBox t = AddTextBox();
 
   // Modify properties outside the proc to
   // simulate generic changed to the
   // control's view state
   t.MaxLength = 5;
   t.BackColor = Color.Yellow;
}

public TextBox AddTextBox() {
   TextBox ctl = new TextBox();
   ctl.Text = "Hello";
   placeHolder.Controls.Add(ctl);
 
   // Records that a dynamic control has been added
   ViewState["AddedControl"] = "true";
   return ctl;
}

You should generate your controls on the PageInit event instead. Controls generated on PageInit are automatically managed by the asp.net framework (you'll get viewstate persistance, raised events, etc...)

Just a side note: On your PageInit, you have to always regenerate the dynamic controls or the framework won't be able to manage them.

Try generating your controls on PageInit, and then changing their properties on the postback event like so:

List<LiteralControl> list = new List<LiteralControl>();

protected void Page_Init(object sender, EventArgs e)
{
    generateTable(); // When pass just here, it works well
}

private void generateTable()
{
    Table tbl = new Table();
    // Here I create my table with controls

    int rows = 3;
    int cols = 2;
    for (int j = 0; j < rows; j++)
    {
        TableRow r = new TableRow();
        for (int i = 0; i < cols; i++)
        {
            TableCell c = new TableCell();
            LiteralControl l = new LiteralControl("row " + j.ToString() + ", cell " + i.ToString());

            // save a reference to the control for editing
            list.Add(l);

            c.Controls.Add(l);
            r.Cells.Add(c);
        }
        tbl.Rows.Add(r);
    }

    tableContainer.Controls.Clear(); // tableContainer is a Panel fixed in aspx page
    tableContainer.Controls.Add(tbl);
}

protected void txt_TextChanged(object sender, EventArgs e)
{
    // edit controls here
    foreach (LiteralControl ctrl in list)
    {
        ctrl.Text = "TextChanged";
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM