我有以下非常简单的代码
<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控件只添加一次。我已经搜索了谷歌和博客网站(加上书籍),但没有任何运气。我错过了什么?
答案 0 :(得分:23)
在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);
}
}
答案 1 :(得分:2)
我同意上面的答案,但是这种方法不会保存动态控件的状态(或者说准确,它会保存状态但不会加载它们)。 在页面生命周期的“加载事件”部分中调用加载视图状态,在此处分配在视图状态中保存的控制值。 但是,如果此时未创建控件,则无法使用以前的数据加载它们,因此要保持状态,必须在加载事件之前或之前重新创建新控件。
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);
}
}
}