ASP.NET dynamic controls (create controls as they become available)

I am trying to create an ASP.NET composite control that allows me to create editable control collections.

My problem is that when I click the add or postback button (which does nothing but return the form), any values ​​entered in the text fields are lost.

I can't get it to work when the number of controls changes between postbacks. I basically need to recreate the control tree two different times in the control life cycle, depending on the state property of the view ControlCount.

This test can be used to reproduce the problem:

public class AddManyControl : CompositeControl
{
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        EnsureChildControls();
    }

    protected override void CreateChildControls()
    {
        var count = ViewState["ControlCount"] as int? ?? 0;

        for (int i = 0; i < count; i++)
        {
            var div = new HtmlGenericControl("div");
            var textBox = new TextBox();
            textBox.ID = "tb" + i;
            div.Controls.Add(textBox);
            Controls.Add(div);
        }

        ViewState["ControlCount"] = count;

        var btnAdd = new Button();
        btnAdd.ID = "Add";
        btnAdd.Text = "Add text box";
        btnAdd.Click += new EventHandler(btnAdd_Click);
        Controls.Add(btnAdd);

        var btnPostBack = new Button();
        btnPostBack.ID = "PostBack";
        btnPostBack.Text = "Do PostBack";
        Controls.Add(btnPostBack);
    }

    void btnAdd_Click(object sender, EventArgs e)
    {
        ViewState["ControlCount"] = (int)ViewState["ControlCount"] + 1;
    }

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
        // If I remove this RecreateChildControls call
        // the collection lags behind each postback
        // because the count is incremented in the btnAdd_Click event handler
        // however, the values are not lost between postbacks
        RecreateChildControls();
    }
}
+5
2

ASP.NET, ! OnPreRender , , 90% .

, ViewState - , , ASP.NET(.NET Reflector !). , .

, , , , , , - :

public class AddManyControl : CompositeControl
{
    private void AddControl(int index)
    {
        var div = new HtmlGenericControl("div");
        var textBox = new TextBox();
        textBox.ID = "tb" + index;
        div.Controls.Add(textBox);
        Controls.AddAt(index, div);
    }

    protected override void CreateChildControls()
    {
        for (int i = 0; i < ControlsCount; i++)
        {
            AddControl(i);
        }

        var btnAdd = new Button();
        btnAdd.ID = "Add";
        btnAdd.Text = "Add text box";
        btnAdd.Click += new EventHandler(btnAdd_Click);
        Controls.Add(btnAdd);

        var btnPostBack = new Button();
        btnPostBack.ID = "PostBack";
        btnPostBack.Text = "Do PostBack";
        Controls.Add(btnPostBack);
    }

    private int ControlsCount
    {
        get
        {
            object o = ViewState["ControlCount"];
            if (o != null)
                return (int)o;

            return 0;
        }
        set
        {
            ViewState["ControlCount"] = value;
        }
    }

    void btnAdd_Click(object sender, EventArgs e)
    {
        int count = ControlsCount;
        AddControl(count);
        ControlsCount = count + 1;
    }
}
+5

, .

-2

All Articles