带 OptionGroup 的 DropDownList






4.79/5 (21投票s)
一个带有 HTML OptionGroup 功能的 ASP.NET DropDownList 自定义控件。
引言
ASP.NET 2.0 缺少 DropDownList
控件中的 OptionGroup 功能 (<optgroup>
)。这意味着无法获得如下所示的 select 控件
使用代码
为了解决此限制,我构建了一个用户渲染控件,适用于 .NET Framework 2.0 或更高版本,具有此功能。此控件支持以下功能(与 .NET 框架中内置的 System.Web.UI.DropDownList
控件一样)
EnableViewState
属性AutoPostBack
属性AppendDataBoundItems
属性SelectedValue
属性- 子项的
Selected
属性 - 引发
ValueChanged
事件 - 支持
DataBind
您可以在设计时使用该控件,如下所示
<ddlb:optiongroupselect id="OptionGroupSelect1" runat="server" enableviewstate="true">
<ddlb:OptionGroupItem ID="OptionGroupItem1"
runat="server" Value="1" Text="ONE" OptionGroup="Odd" />
<ddlb:OptionGroupItem ID="OptionGroupItem2"
runat="server" Value="2" Text="TWO" OptionGroup="Even" />
<ddlb:OptionGroupItem ID="OptionGroupItem3"
runat="server" Value="3" Text="TREE" OptionGroup="Odd" />
<ddlb:OptionGroupItem ID="OptionGroupItem4"
runat="server" Value="4" Text="FOUR" OptionGroup="Even" />
</ddlb:optiongroupselect>
属于同一 OptionGroup 的项目不必紧挨着放置。
或者,如果您希望在代码中使用该控件
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this.OptionGroupSelect1.Items.Add(new OptionGroupItem("A",
"Letter A", "Letters"));
this.OptionGroupSelect1.Items.Add(new OptionGroupItem("B",
"Letter B", "Letters"));
this.OptionGroupSelect1.Items.Add(new OptionGroupItem("C",
"Letter C", "Letters"));
}
}
关注点
本文附带的解决方案由两个项目组成。第一个是类库,其中包含控件及其相关类的源代码,第二个是 Web 应用程序,其中包含用于测试控件行为的一些页面。
在项目库中,我们可以找到以下类
OptionGroupSelect
是该控件。它继承自DataBoundControl
,最终扩展了WebControl
类。我扩展了DataBoundControl
类,因为它被用作所有以列表形式显示其数据的 ASP.NET 2.0 数据绑定控件的基类。这个基类为我提供了执行渲染控件的数据绑定操作的功能。OptionGroupItem
代表具有相对属性的单个“列表项”:Text
、Value
、OptionGroup
和Selected
。它继承自WebControl
类,并且仅重写了Render
方法。OptionGroupSelectControlDesigner
用于执行设计时控件渲染。OptionGroupItemBuilder
用于通知父控件OptionGroupSelect
,已分析 HTML 元素并将其添加到父控件的 ControlCollection 属性。从本质上讲,它允许我在设计时创建子项。
主控件 (OptionGroupSelect
) 重写了 LoadViewState
方法以检索视图状态值,用于维护控件状态。因此,SaveViewState
也被重写了。
由于控件实现了 IPostBackDataHandler
接口,因此重写了 LoadPostData
方法以检测所选值是否因任何用户选择而改变。在这种情况下,它返回 true,因此触发了 ValueChanged
事件。
在 Render
方法中,我绘制了 select
HTML 控件,添加了 optgroup
元素,并且对于每个子列表项,调用了相对的 RenderControl
方法。
如果子项定义了 OptionGroup
属性,我将它们按此值分组,因此具有相同 OptionGroup
的项目会被安排在一起。没有 OptionGroup
值的项目会被正常处理。
正如我所说,主控件扩展了 DataBoundControl
类。这意味着必须重写一些方法才能获得数据绑定行为。这些方法是
PerformSelect
:由于DataBind
调用,将调用此方法。它提取数据源并将其作为IEnumerable
对象公开。有趣的是,数据源对象不必是DataSet
。它也接受DataTable
、DataView
或List<OptionGroupItem>
。此外,代码内部使用的this.GetData()
方法从DataSet
提取一个DataSourceView
对象,该对象指向DataMember
属性所指定的DataTable
。PerformDataBinding
:此方法执行实际工作。对于每个项目,都会创建一个OptionGroupItem
实例并将其添加到OptionGroupSelect
子控件的Controls
集合中。
有关自定义数据绑定的更多详细信息,请访问 MSDN。