正如Pranay所解释的那样,这是因为您正在动态添加控件。您需要在postback之前重建页面。此外,当涉及到记住先前显示的信息时,Table控件不是一个好的Web控件。您可能会更幸运地使用Repeater、DataList或DataGrid。可以在Deciding When to Use the DataGrid, DataList or Repeater(MSDN)中进行比较。
为了演示,我可以展示一个简短的例子,说明如何实现Repeater,因为在我看来,这是最简单的控件之一。因此,不要在postback(例如按钮单击)中添加表格,而是在标记中添加repeater,并在需要显示数据时将其设置为可见。这样,您甚至不必担心动态控件,它在您需要时就在那里。
因此,带有复选框的repeater的基本标记如下。
<asp:Repeater ID="myTable" runat="server">
<HeaderTemplate>
<table cellpadding="4" cellspacing="0">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Company</th>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:HiddenField ID="uidfield" Value='<%# Eval("Uid") %>' runat="server" />
<asp:CheckBox ID="valuefield" Checked='<%# Eval("IsChecked") %>' runat="server" />
</td>
<td>
<asp:Label Text='<%# Eval("Name") %>' runat="server" />
</td>
<td>
<asp:Label Text='<%# Eval("Company") %>' runat="server" />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</tbody> </table>
</FooterTemplate>
</asp:Repeater>
正如您所看到的,该表是手动构建的(如果您不想这样做,可以使用DataGrid代替)。现在您可以拥有一个类作为您的模型,例如:
public class Person {
public Person() { }
public Person(Guid id, string name, string company) {
this.Uid = id;
this.Name = name;
this.Company = company;
}
public Guid Uid { get; set; }
public string Name { get; set; }
public string Company { get; set; }
}
还有一个视图模型类,它“满足”视图的需求(例如您的网页控件)。请注意额外的属性IsChecked,它不应该是模型的一部分(人如何被检查?),但它很适合于视图模型类。
public class PersonViewModel {
private Person model;
public PersonViewModel(Person model) {
this.model = model;
}
public Guid Uid { get { return model.Uid; } }
public string Name { get { return model.Name; } }
public string Company { get { return model.Company; } }
public bool IsChecked { get; set; }
}
好的,接下来是代码部分。当使用重复器控件时,您需要将其绑定到一个列表上。从IEnumerable继承的实例就可以了,所以您需要将它连接起来。
在页面的代码后面,添加这些方法。
protected override void OnInit(EventArgs e) {
base.OnInit(e);
mailinglists.DataBinding += bindMyTable;
}
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
if (!Page.IsPostBack) {
DataBind();
}
}
private void bindMyTable(object sender, EventArgs e) {
if (conditionsMet()) {
myTable.DataSource = getDataSource();
}
}
private IEnumerable<PersonViewModel> getDataSource() {
List<PersonViewModel> view = new List<PersonViewModel>();
view.Add(new PersonViewModel(new Person() { Uid = Guid.NewGuid(), Name = "Example", Company = "Co" }));
return view;
}
现在只需在条件满足时调用
myTable.DataBind()
,例如当您单击按钮时。当您单击按钮并需要检查哪些复选框已选中时,您可以使用
repeater.Items
属性来迭代它们,类似于以下内容:
private void onValidatePage() {
List<Guid> checks = new List<Guid>();
foreach (RepeaterItem repeatitem in myTable.Items) {
string uid = ((HiddenField)repeatitem.FindControl("uidfield")).Value;
bool value = ((CheckBox)repeatitem.FindControl("valuefield")).Checked;
if (value) {
checks.Add(new Guid(uid));
}
}
}