背景
我有一个用户控件(.ascx文件)正在动态插入页面上的asp:PlaceHolder控件。该用户控件包含一个asp:Repeater,我绑定到DataTable。
理论上,在User Control的第一次加载时,DataTable被初始化并添加了3个空行。用户控件上的按钮会向Repeater添加额外的空行,一次一个。
问题
问题是在页面上的任何PostBack事件(即单击此示例中的按钮)之后,Repeater的DataTable为空。
用户控制(.ascx) (简化的)
<asp:TextBox ID="controlOutsideRepeater" runat="server" />
<asp:Repeater ID="myRepeater" runat="server">
<ItemTemplate>
<p><asp:Textbox ID="firstControlInRepeater" runat="server" text='<%# DataBinder.Eval(Container.DataItem, "A") %>' /></p>
<p><asp:Textbox ID="secondControlInRepeater" runat="server" text='<%# DataBinder.Eval(Container.DataItem, "B") %>' /></p>
</ItemTemplate>
</asp:Repeater>
<asp:LinkButton ID="addItemButton" runat="server" Text="Add Item" onclick="addNewItem" />
代码背后(.ascx.cs) (也简化)
public DataTable items {
get {
object i = ViewState["items"];
if (i == null) {
DataTable t = new DataTable();
t.Columns.Add("A");
t.Columns.Add("B");
// add 3 blank items/rows:
t.Rows.Add(t.NewRow());
t.Rows.Add(t.NewRow());
t.Rows.Add(t.NewRow());
ViewState["items"] = t;
return t;
} else {
return (DataTable)i;
}
set { ViewState["items"] = value; }
}
protected void Page_Init(object sender, EventArgs e) {
myRepeater.DataSource = this.items;
myRepeater.DataBind();
}
public void addNewItem(object sender, EventArgs e) {
DataRow r = this.items.NewRow();
this.items.Rows.Add(r);
myRepeater.DataBind();
}
行为
第一次加载UserControl时,Repeater包含3个空项:好!但是,在转发器内部和外部的文本框中输入一些文本并单击“添加项目”LinkButton后,页面将执行刷新/回发并显示4个空项目,但文本框 - 外部 - Repeater保留其文本。单击“添加项目”LinkButton再次执行回发并仍显示4个空项目,但Repeater外部的TextBox再次保留其文本。
我的疯狂猜测
我已经尝试将Repeater数据绑定包装在(!Page.IsPostBack)中,但是这阻止了Repeater被绑定,因为UserControl只是在PostBack(按钮上)之后以编程方式添加到页面中页面在单击时添加UserControl,然后页面检查每个PostBack以查看是否存在用户控件并在需要时将其重新添加到页面中。因此我猜测在每个PostBack上重新创建用户控件的页面存在问题,但无法解释为什么Repeater外部的TextBox会保留它的值,以及为什么ViewState似乎不记得我的项目(在每个回发上,ViewState [“items”]为空并在getter中重新构建。
HELP!
答案 0 :(得分:1)
问题是当你真正想要在第一个请求上进行数据绑定时,你是每个请求的数据绑定。由于您没有在第一页加载时进行数据绑定,因此您必须检查是否是以.Page.IsPostBack以外的方式绑定数据。您可以向用户控件添加一个属性来处理此问题,然后检查每个页面加载/页面初始化。
更新:提供更多评论详情
我现在看到你的AddItem()了。虽然我不完全确定原因,但我在使用viewstate时遇到了问题。我必须更像下面这样做:
public void addNewItem(object sender, EventArgs e) {
DataTable theItems = this.items;
DataRow r = theItems.NewRow()
theItems.Rows.Add(r);
this.items = theItems
myRepeater.DataBind(); //I'm not sure if this belongs here because of the reasons said before
}