如何在 ASP.NET 中隐藏 RadioButtonList 或 CheckBoxList 的 ListItem





1.00/5 (4投票s)
2006年5月2日
3分钟阅读

94968

495
本文演示了如何在 ASP.NET 中隐藏 RadioButtonList 或 CheckBoxList 的 ListItems,而无需创建自己的自定义 Web 控件。
引言
随着 ASP.NET 大约五年前的出现,微软创建了几个内置的 Web Forms 控件,其中包括 RadioButtonList 和 CheckboxList。这两个控件拥有相当健壮且直观的类结构,但在一个非常实用的方面却有所欠缺:隐藏其各个 ListItems 的能力!
背景
我必须承认,在 RadioButtonList 或 CheckBoxList 中隐藏各个 ListItems 并不是开发人员日常需要做的事情。然而,当出于实际原因需要隐藏它们时,可能会相当令人沮丧。在其中一个案例中,我需要为 RadioButtonList 设置一个默认值,但又不希望用户看到它,而是希望通过 SelectedItem 属性以编程方式引用它。在尝试了几种其他方法并在网上搜索了其他解决方案后,我清楚地意识到我必须自己创造解决方案。我相信结果是一个很好的变通方法,它足够灵活,开发人员可以在现有应用程序中使用它,而无需引用外部 .dll 文件或 Web 控件库。
我最初的隐藏 ListItems 方法……结果无效
我最初解决这个问题的方法是引用 RadioButtonList 或 CheckBoxList 控件的 Items 集合中的 ListItem 对象,并添加一个样式属性来设置其显示样式为“none”。现在,一个理性的人会认为这会起作用,因为它不会引起编译或运行时错误。然而,当控件作为 HTML 呈现给浏览器时,源代码中指定的属性根本不会被渲染!
这是我最初隐藏 ListItem 的想法,但没有成功
Public Shared Sub HideListItem(ByRef RbList As RadioButtonList)
'This code doesn't work although logically you might think that it would!
RbList.Items(0).Attributes.Add("style", "display='none;'")
End Sub
Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender
HideListItem(Me.rbGender)
End Sub
当页面加载并且您查看页面的 HTML 源代码时,它看起来是这样的:
<table id="rbGender" border="0" style="width:136px;">
<tr>
<td><input id="rbGender_0" type="radio" name="rbGender" value="-1" /><label for="rbGender_0">-1</label></td>
<td><input id="rbGender_1" type="radio" name="rbGender" value="0" /><label for="rbGender_1">Female</label></td>
<td><input id="rbGender_2" type="radio" name="rbGender" value="1" /><label for="rbGender_2">Male</label></td>
</tr>
</table>
您会注意到属性“style=display='none;'”无处可寻!
一种可行的方法!通过使用动态生成的 DHTML 隐藏 ListItem
由于我指定的样式属性没有被代码正确渲染,我决定采取另一种方法。通过利用我对 DHTML 的了解,我决定动态生成一些 DHTML 来为我隐藏 ListItems。
请查看下面的代码以获取更多详细信息:
Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender
'Get the JavaScript code that will hide the ListItem
Dim jsCode As String = HideRadioButtonListItem(Me.rbGender)
'use RegisterStartupScript to make sure
'that this javascript is placed after the RadioButtonList HTML has rendered
Me.RegisterStartupScript("HideListItems", jsCode)
End Sub
'Use this method if you want to hide the first item in the list
Public Function HideRadioButtonListItem(ByRef RbList As RadioButtonList) As String
Dim IndexesHide() As String = {"0"}
Return HideRadioButtonListItems(RbList, IndexesHide)
End Function
'Use this method if you want to hide multiple Items of various indexes
'For example: HideRadioButtonListItems(Me.rbGender, "0,2".Split(","c))
'Would hide the first and third items in the RadioButtonList
Public Function HideRadioButtonListItems(ByRef RbList As RadioButtonList, ByVal IndexesToHide() As String) As String
Dim HideColumnOrRowBasedOnRepeatDirection As String = ""
'Determine whether an HTML row or column is to be hidden
'based on the Repeat direction
If RbList.RepeatDirection = RepeatDirection.Horizontal Then
HideColumnOrRowBasedOnRepeatDirection = "td"
ElseIf RbList.RepeatDirection = RepeatDirection.Vertical Then
HideColumnOrRowBasedOnRepeatDirection = "tr"
End If
'Get the ClientID that will be used when the control is rendered to the client in HTML
Dim CtrlClientID As String = RbList.ClientID
'The .NET Framework recommends that you use a StringBuilder class instead of a String DataType
'when dealing with potentially large strings
Dim JScriptCodeString As New System.Text.StringBuilder
'Build the javascript that will do the hiding of the items
JScriptCodeString.Append(" <script language=" + Chr(34) + "javascript" + Chr(34) + "> " & vbCrLf)
JScriptCodeString.Append(" var rbTable;" & vbCrLf)
JScriptCodeString.Append(" rbTable = document.getElementById(""" & CtrlClientID & """);" & vbCrLf)
JScriptCodeString.Append(" if ((rbTable == null) || (rbTable == undefined)) { } else { " & vbCrLf)
JScriptCodeString.Append(" var NestedLabels;" & vbCrLf)
JScriptCodeString.Append(" NestedLabels = rbTable.getElementsByTagName(""")
JScriptCodeString.Append(HideColumnOrRowBasedOnRepeatDirection & """);" & vbCrLf)
For i As Integer = 0 To IndexesToHide.Length - 1
JScriptCodeString.Append(" NestedLabels[" & IndexesToHide(i) & "].style.display = ""none"";" & vbCrLf)
Next
JScriptCodeString.Append(" } " & vbCrLf)
JScriptCodeString.Append(" </script> " & vbCrLf)
Return JScriptCodeString.ToString()
End Function
这是 ASP.NET HTML 源代码:
<body >
<form id="Form1" method="post" runat="server">
<P>Choose Gender (optional) : </P>
<P><asp:RadioButtonList id=rbGender runat="server" Width="200px" RepeatDirection="Horizontal">
<asp:ListItem Value="-1">-1</asp:ListItem>
<asp:ListItem Value="0">Female</asp:ListItem>
<asp:ListItem Value="1">Male</asp:ListItem>
</asp:RadioButtonList></P>
</form>
</body>
当页面运行时,这是呈现给浏览器的 HTML 源代码:
<body >
<form name="Form1" method="post" action="WebForm1.aspx" id="Form1">
<input type="hidden" name="__VIEWSTATE" value="dDwtMTQ2MTEwNDc7Oz5KPbuB9pD1EtgvbuBPmJmyEQ9ORQ==" ID="Hidden1"/>
<P>Choose Gender (optional) : </P>
<P><table id="rbGender" border="0" style="width:200px;">
<tr>
<td><input id="rbGender_0" type="radio" name="rbGender" value="-1" /><label for="rbGender_0">-1</label></td>
<td><input id="rbGender_1" type="radio" name="rbGender" value="0" /><label for="rbGender_1">Female</label></td>
<td><input id="rbGender_2" type="radio" name="rbGender" value="1" /><label for="rbGender_2">Male</label></td>
</tr>
</table></P>
<script language="javascript">
var rbTable;
rbTable = document.getElementById("rbGender");
if ((rbTable == null) || (rbTable == undefined)) { } else {
var NestedLabels;
NestedLabels = rbTable.getElementsByTagName("td");
NestedLabels[0].style.display = "none";
}
</script>
</form>
</body>
基本上,代码接收 RadioButtonList 的引用,并使用其 ClientID(ASP.NET 在将控件呈现给客户端浏览器之前生成的服务器控件标识符)属性,使用 **document.getElementById** Javascript 函数来访问它。然后,我确定重复方向是水平还是垂直,并获取 HTML 元素的全部列或行。由于 ListItem 的索引与呈现的 RadioButtonList HTML 表中的列或行集合完全匹配,因此我能够根据开发人员决定的指定索引来隐藏行或列。
嘿,那 CheckBoxList 呢?
我没有忘记我们老朋友 CheckboxList。为了保持本文简洁,我没有添加 CheckboxList 的代码。正如您可能已经知道的,这两个控件很相似,它们都有一个 Items 集合和一个 RepeatDirection 属性。我希望它们都继承自一个具有这两个关键属性的 BaseClass。不幸的是,它们继承的 ListControl 类有一个 Items 集合属性,但没有 .RepeatDirection 属性。所以,我决定为它们各自创建单独的重载方法。
当您下载源代码和项目文件时,您会看到专门用于 CheckboxList 和 RadioButtonList 的方法,以及将此功能集成到您的应用程序中的其他很酷的方法。由于我精通 C# 和 VB,我提供了 **C#** 和 **VB.NET** 两种 **源代码**。因此,您可以根据需要直接复制粘贴。
结论
我希望这种方法能够帮助您在 CheckboxList 或 RadioButtonList 中隐藏或显示 ListItems。请随时在此基础上进行扩展,为您的各个 ListItems 创建其他功能。这个概念的一些很酷的实现方式可以是禁用单个 ListItems 或添加自定义客户端的 onclick 事件。
长生不老,代码规范!
历史
目前没有修订……