ASP Repeater后台生成CheckBox,C#中FindControl获取控件失败求助
解决ASP.NET Repeater中动态生成CheckBox无法通过FindControl获取的问题
核心原因
Repeater是数据绑定容器控件,你动态生成的relBtn或rfBtn属于Repeater的RepeaterItem(每一行的独立容器),并非直接挂载在mainPanel下。直接调用mainPanel.FindControl("relBtn")自然找不到,因为控件不在这个层级。
解决方案步骤
1. 确保动态控件在回发时重新生成
ASP.NET控件树每次回发都会重建,动态生成的控件必须在Page_Init或Page_Load阶段(回发时也要执行)重新创建并添加到Repeater的对应Item中,否则回发时控件会丢失——哪怕页面源码能看到,服务器端控件树里也不存在。
示例代码(推荐把生成逻辑放在Repeater的ItemDataBound事件中):
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e) { if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) { string role = DataBinder.Eval(e.Item.DataItem, "Role").ToString(); CheckBox cb = new CheckBox(); if (role == "Rel") { cb.ID = "relBtn"; cb.Text = "Rel选项"; } else { cb.ID = "rfBtn"; cb.Text = "RF选项"; cb.Checked = true; } // 将CheckBox添加到RepeaterItem内部的容器(比如预先在前台放的Placeholder) PlaceHolder ph = e.Item.FindControl("itemPlaceholder") as PlaceHolder; ph.Controls.Add(cb); } }
2. 遍历Repeater Items查找目标控件
在showChosen方法中,不能直接从mainPanel找,需要遍历Repeater的每一个RepeaterItem,在Item内部查找relBtn:
protected void showChosen(object sender, EventArgs e) { foreach (RepeaterItem item in Repeater1.Items) { if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem) { CheckBox relBtn = item.FindControl("relBtn") as CheckBox; if (relBtn != null) { bool isChecked = relBtn.Checked; // 执行你的后续逻辑 break; // 只找第一个匹配项的话,找到后跳出循环 } } } }
3. 注意控件命名容器的影响
Repeater的每个Item都是独立的命名容器,动态生成的控件ID会被自动加上容器前缀(比如Repeater1_ctl00_relBtn),所以不能用客户端看到的完整ID去服务器端FindControl,必须在对应的Item内部查找。
额外提示
- 不要在
Page_PreRender阶段生成动态控件,这个阶段太晚,回发时控件无法被正确初始化和加载状态。 - 如果需要定位特定行的控件,可以结合Repeater数据源的主键,遍历Item时通过
DataItem获取主键值,判断是否为目标行后再查找控件。
内容的提问来源于stack exchange,提问作者Henry B
相关产品推荐
相关产品推荐

