Как динамически создавать / удалять элементы управления с помощью EventHandlers на странице ASP.NET?

В одном из моих проектов мне нужно создать страницу ASP.NET, а некоторые элементы управления должны быть созданы динамически. Эти элементы управления добавляются на страницу классом code-behind, и к ним добавляются некоторые обработчики событий. В PostBacks эти обработчики событий имеют много общего с тем, какие элементы управления затем отображаются на странице. Короче говоря, это не работает для меня, и я, кажется, не могу понять это.

Итак, поскольку мой проект довольно сложный, я решил создать короткий пример, который тоже не работает, но если вы можете настроить его так, чтобы он работал, это было бы здорово, и тогда я смог бы применить ваше решение к моему оригиналу проблема.

Следующий пример должен динамически создавать три кнопки на панели. Когда нажата одна из кнопок, все кнопки должны быть динамически воссозданы, за исключением кнопки, которая была нажата. Другими словами, просто скройте кнопку, которую нажимает пользователь, и покажите две другие.

Чтобы ваше решение было полезным, вы не можете статически создавать кнопки, а затем использовать свойство Visible (или радикально изменить пример другими способами) - вам нужно заново динамически создавать все элементы управления кнопками для каждого PostBack (не обязательно в хотя обработчик событий). Это не вопрос с подвохом - я действительно не знаю, как это сделать. Большое спасибо за ваши усилия. Вот мой короткий пример:

Из файла Default.aspx:

<body>
    <form id="form1" runat="server">
    <div>
        <asp:Panel ID="ButtonsPanel" runat="server"></asp:Panel>
    </div>
    </form>
</body>

Из файла кода code.aspx.cs:

using System;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace DynamicControls
{
    public partial class _Default : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            AddButtons();
        }

        protected void AddButtons()
        {
            var lastClick = (string) Session["ClickedButton"] ?? "";

            ButtonsPanel.Controls.Clear();
            if (!lastClick.Equals("1")) AddButtonControl("1");
            if (!lastClick.Equals("2")) AddButtonControl("2");
            if (!lastClick.Equals("3")) AddButtonControl("3");
        }

        protected void AddButtonControl(String id)
        {
            var button = new Button {Text = id};
            button.Click += button_Click;
            ButtonsPanel.Controls.Add(button);
        }

        private void button_Click(object sender, EventArgs e)
        {
            Session["ClickedButton"] = ((Button) sender).Text;
            AddButtons();
        }
    }
}

В моем примере показаны три кнопки, и когда я нажимаю одну из кнопок, нажатая кнопка скрывается. Кажется работать; но после этого первого щелчка я должен щелкнуть каждую кнопку ДВАЖДЫ, чтобы она скрылась.!?

5 ответов

Решение

Я думаю, что вы должны предоставлять один и тот же идентификатор для ваших кнопок каждый раз, когда вы добавляете их, например, так (в первой строке AddButtonControl метод):

var button = new Button { Text = id , ID = id };

РЕДАКТИРОВАТЬ - Мое решение без использования сессии:

public partial class _Default : Page
{
    protected override void OnPreInit(EventArgs e)
    {
        base.OnPreInit(e);
        AddButtons();
    }

    protected void AddButtons()
    {
        AddButtonControl("btn1", "1");
        AddButtonControl("btn2", "2");
        AddButtonControl("btn3", "3");
    }

    protected void AddButtonControl(string id, string text)
    {
        var button = new Button { Text = text, ID = id };
        button.Click += button_Click;
        ButtonsPanel.Controls.Add(button);
    }

    private void button_Click(object sender, EventArgs e)
    {
        foreach (Control control in ButtonsPanel.Controls)
            control.Visible = !control.Equals(sender);
    }
}

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

Смотрите здесь для жизненного цикла страницы ASP.NET: http://msdn.microsoft.com/en-us/library/ms178472.aspx

При добавлении событий вам нужно сделать это не позднее Page_Load метод, и они должны быть добавлены каждый запрос, то есть вы никогда не должны переносить назначение события в !IsPostBack,

Вам также необходимо создавать динамические элементы управления для любого отдельного запроса. ViewState не будет обрабатывать отдых от вашего имени.

Я заметил одну вещь: когда вы нажимаете кнопку, вы вызываете AddButtons() дважды, один раз в Page_Load() и однажды в button_Click() метод. Вы, вероятно, должны обернуть один в Page_Load() в if (!IsPostBack) блок.

if (!IsPostBack)
{
   AddButtons();
}

Элементы управления, которые добавляются динамически, не кэшируются, так что это одна из ваших проблем

AFAIK, создание элементов управления должно быть размещено не в Page_Load, а в Page_PreInit (ViewState и SessionState загружаются до Page_Load, но после Page_PreInit).

С вашей проблемой я бы предложил отладить функцию AddButtons, чтобы выяснить, что именно (и когда) хранится в Session["ClickedButton"]. Затем вы должны быть в состоянии выяснить проблему.

Другие вопросы по тегам