Подсчет динамических элементов управления в ASP.NET (создание элементов управления на ходу) - PullRequest
5 голосов
/ 28 января 2011

Я пытаюсь создать составной элемент управления ASP.NET, который позволит вам создать редактируемую коллекцию элементов управления.

Моя проблема в том, что когда я нажимаю кнопку добавления или отправки (которая не делает ничего, кроме отправки формы), все значения, введенные в текстовые поля, теряются.

Я не могу заставить его работать, когда количество элементов управления изменяется между постбэками. Мне нужно иметь возможность воссоздавать дерево элементов управления в два разных периода жизненного цикла элемента управления в зависимости от свойства состояния представления ControlCount.

Этот тест можно использовать для воспроизведения проблемы:

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();
    }
}

Ответы [ 2 ]

5 голосов
/ 30 января 2011

Если вы хотите играть с пользовательскими элементами управления 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;
    }
}
0 голосов
/ 28 января 2011

Я считаю, что вы должны добавить элемент управления в состояние просмотра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...