如何在ascx的for-each循环中为asp:CheckBox控件动态设置ID
问题根因
你原来的写法不生效是因为runat="server"的ASP.NET服务端控件的属性在页面生命周期的解析阶段就会被处理,而<%= %>是页面渲染阶段才执行的内联表达式,二者执行时机不匹配,所以不能直接用来给服务端控件的ID赋值。
解决方案1:使用原生HTML复选框(最简便,适配你的需求)
如果你的需求仅为传递选中的ID,不需要用到服务端CheckBox的服务端事件特性,直接改用原生的<input type="checkbox">是最省心的方案,可以自由设置value值,提交时直接获取选中项的value即可,代码如下:
<% For each row As DataRow In myDataTable.Rows %> <%=row("something") %> <%=row("somethingelse") %> <input type="checkbox" name="selectedIds" value="<%=row("MyId")%>" /> <% next %>
提交表单的时候,直接从请求参数里取selectedIds就能拿到所有被勾选的ID集合,无需额外处理。
解决方案2:坚持使用服务端CheckBox的实现方式
如果需要用到服务端CheckBox的其他服务端特性,可以改用Repeater数据绑定控件来渲染,避免在循环里手动写服务端控件:
- 首先在ascx页面写Repeater模板:
<asp:Repeater ID="rptData" runat="server"> <ItemTemplate> <%# Eval("something") %> <%# Eval("somethingelse") %> <asp:CheckBox ID="chkItem" runat="server" /> </ItemTemplate> </asp:Repeater>
- 后台代码绑定数据,同时给CheckBox绑定自定义属性存ID:
' 绑定数据源 rptData.DataSource = myDataTable rptData.DataBind() ' 在Repeater的ItemDataBound事件里给CheckBox赋值 Private Sub rptData_ItemDataBound(sender As Object, e As RepeaterItemEventArgs) Handles rptData.ItemDataBound If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then Dim row As DataRow = DirectCast(e.Item.DataItem, DataRowView).Row Dim chk As CheckBox = DirectCast(e.Item.FindControl("chkItem"), CheckBox) ' 把业务ID存在自定义属性里,不直接修改服务端控件ID chk.Attributes("data-id") = row("MyId").ToString() End If End Sub
- 提交时遍历Repeater的项,获取选中的ID:
Dim selectedIds As New List(Of String)() For Each item As RepeaterItem In rptData.Items Dim chk As CheckBox = DirectCast(item.FindControl("chkItem"), CheckBox) If chk.Checked Then selectedIds.Add(chk.Attributes("data-id")) End If Next
注意:不建议直接修改服务端控件的ID属性,ASP.NET服务端控件的ID有命名规则限制,不能包含特殊字符、不能以数字开头,动态修改可能会导致页面回发时找不到控件的异常,用自定义属性存储业务ID是更稳妥的方案。
内容的提问来源于stack exchange,提问作者AbsoluteBeginner
相关产品推荐
相关产品推荐

