Динамическое добавление элементов управления в панель обновления в ASP.NET AJAX - PullRequest
13 голосов
/ 16 февраля 2009

У меня есть следующий действительно простой код

<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
    <asp:PlaceHolder ID="PlaceHolder1" runat="server">
    </asp:PlaceHolder>
    <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
</ContentTemplate>
</asp:UpdatePanel>

И код позади

protected void Button1_Click(object sender, EventArgs e)
{
    Literal literal = new Literal();
    literal.Text = DateTime.Now.ToString();
    literal.ID = DateTime.Now.Ticks.ToString();

    // These both work fine the first time the button is clicked
    // but the second time nothing is added.
    UpdatePanel1.ContentTemplateContainer.Controls.Add(literal);
    PlaceHolder1.Controls.Add(literal);
}

Моя проблема заключается в том, что элемент управления Literal добавляется только один раз. Я искал сайты Google и блогов (плюс книги), но безуспешно. Чего мне не хватает?

Ответы [ 2 ]

23 голосов
/ 16 февраля 2009

В asp.net элементы управления в файле ASPX автоматически генерируются при каждой обратной передаче. Созданные вами элементы управления не содержатся в коде ASPX, поэтому инфраструктура не создает их для вас. При первом запуске метода Button1_Click на страницу добавляется один дополнительный элемент управления. Во второй раз, когда вы выполняете метод Button1_Click, вы возвращаетесь к другому сообщению, и об этой первой дополнительной кнопке забыли. В результате этого постбэка вы снова получаете одну дополнительную кнопку.

Это создаст один дополнительный элемент управления при каждом нажатии кнопки (хотя отметки времени будут обновляться при каждом нажатии кнопки, поскольку элементы управления создаются заново)

protected void Button1_Click(object sender, EventArgs e)
{
    int count = 0;

    if (ViewState["ButtonCount"] != null)
    {
        count = (int)ViewState["ButtonCount"];
    }

    count++;
    ViewState["ButtonCount"] = count;

    for (int i = 0; i < count; i++)
    {
        Literal literal = new Literal();
        literal.Text = DateTime.Now.ToString();
        literal.ID = DateTime.Now.Ticks.ToString();

        UpdatePanel1.ContentTemplateContainer.Controls.Add(literal);
        PlaceHolder1.Controls.Add(literal);
    }            
}
2 голосов
/ 23 августа 2014

Я согласен с ответом выше, однако этот подход не сохранит состояние динамических элементов управления (или, если быть точным, он сохранит состояние, но не загрузит их обратно). Состояние просмотра загрузки вызывается в разделе «Событие загрузки» жизненного цикла страницы, где оно присваивает обратно значения управления, сохраненные в состоянии просмотра. Однако, если элементы управления не созданы к этому времени, они не могут быть загружены с предыдущими данными, поэтому для сохранения состояния новые элементы управления должны быть воссозданы во время или перед событием загрузки.

protected void Page_Load(object sender, EventArgs e)
{
    //PS: Below approach saves state as id is constant, it simply generates a new control with same id hence viewstate loads the value
    if (IsPostBack)
    {
        int count = 0;

        if (ViewState["ButtonCount"] != null)
        {
            count = (int)ViewState["ButtonCount"];
        }

        count++;
        ViewState["ButtonCount"] = count;

        for (int i = 0; i < count; i++)
        {
            TextBox literal = new TextBox();
            //literal.Text = DateTime.Now.ToString();
            literal.ID = "Textbox" + i.ToString();

            //UpdatePanel1.ContentTemplateContainer.Controls.Add(literal);
            PlaceHolder1.Controls.Add(literal);

        }
    }
}

Динамическое добавление элементов управления Просмотр состояния и обратной передачи

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