在ASP.NET AJAX中动态向UpdatePanel添加控件

14
我有以下非常简单的代码。
<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 control)只会添加一次。我已经搜索了谷歌和博客网站(还有书),但都没有找到解决方法。我错过了什么吗?

2个回答

25
在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);
    }            
}

4
我同意以上答案,但是这种方法无法保存动态控件的状态(或者准确地说,它会保存状态,但不会将其加载回来)。页面生命周期中的Load事件部分会调用Load view state函数,它会将保存在视图状态中的控件值重新赋值回去。然而,如果这个时候控件还没有被创建,它们就不能被加载回先前的数据。所以为了保持状态,新的控件必须在Load事件之前被重新创建。
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);

        }
    }
}

动态添加控件 视图状态和回发


3
同意,这样做更好。在回传过程中保持ID不变可以正确应用视图状态。然而,根据http://msdn.microsoft.com/en-us/library/ms972976.aspx,这应该在页面的Init中完成。 - Guy Lowe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接