用ASP.NET用了很多年,以为已经很熟悉了;昨天遇到一个问题,居然回答不出来;把问题扩充一下,然后翻遍所有资料都没有找到答案;就写写吧;
页面很简单,一个Label, 一个 Repeater1 组件,里面的 Header 有一个 CheckBox, 点击该CheckBox, 改变 Label的值,表示该哪个CheckBox触发以及该CheckBox的状态;
代码如下,
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
var xx = new object[] { };
this.Repeater1.DataSource = xx;
this.Repeater1.DataBind();
foreach (RepeaterItem aitem in Repeater1.Controls)
{
if (aitem.ItemType == ListItemType.Header)
{
CheckBox ck = (CheckBox)aitem.FindControl("HeadCheckBox");
ck.AutoPostBack = true;
ck.CheckedChanged += ck_CheckedChanged;
}
}
}
protected void ck_CheckedChanged(object sender, EventArgs e)
{
CheckBox cb = (CheckBox)sender;
var lbText = cb.ClientID + (cb.Checked ? " checked" : " not checked");
this.Label1.Text = lbText;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</div>
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<asp:CheckBox ID="HeadCheckBox" runat="server" Text="Head"/>
</HeaderTemplate>
</asp:Repeater>
<br />
</form>
</body>
</html>
然后就发现,怎么点击那个 CheckBox,都无法触发事件;页面初始化过程,这个似乎比较好理解;
因为,根据我的理解,在Page_Load之前,Page 应该会根据提交回去的数据(主要是根据ViewState和页面内容)构建控件树,此时将会重新Repeater1的Head里面将会有一个CheckBox,(这个CheckBox应该会记得需要触发CheckedChanged 事件),但在Page_Load事件中,对 Repeat1进行了重新绑定,此时原来的已经注册了CheckedChanged 事件的CheckBox控件将从Page中移除(移除的同时估计该控件注册的CheckedChanged 事件也从Page中移除);
所以,上面的代码估计如果改成:
if (!this.IsPostback){
var xx = new object[] { };
this.Repeater1.DataSource = xx;
this.Repeater1.DataBind();
}
就可以正常触发 CheckBox的CheckedChanged事件了;果然,结果证实了我的猜想;
但是。。。。。真的是这样吗?