65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET 控件显示枚举值

2007 年 3 月 30 日

CPOL

4分钟阅读

viewsIcon

70750

downloadIcon

200

可以自动显示枚举值的 RadioButtonList 和 ListBox 子类。

引言

枚举很棒。它们定义了一组允许的值,并为函数和方法的参数提供了一种类型检查方式。问题在于枚举和用户界面之间存在一些差距。因此,我创建了 RadioButtonEnumListBoxEnum 控件,允许您自动将控件绑定到 Enum 类型。

背景

我厌倦了手动构建这些 UI 组件,并意识到不应该将值和文本从类复制到 UI,因为 .NET 框架可以为我完成这项工作。

使用代码

您的代码中多久会出现这种情况

Public Enum Genders
  Male
  Female
End Enum

因此,界面组件也是如此

<asp:RadioButtonList ID="RadioButtonList1" runat="server">
  <asp:ListItem Value="0" Text="Male" />
  <asp:ListItem Value="1" Text="Female" /> 
</asp:RadioButtonList>

然后代码发生变化,例如

Public Enum Genders
  NotSpecified
  Male
  Female
End Enum

现在您的界面控件不匹配了,一个现有的值 1(最初是 female)现在显示为“Male”,并且如果您尝试将 SelectedValue 绑定到 2(Female)时会抛出异常。

方法

我意识到,通过继承 RadioButtonList 并告诉它从给定的 Enum 类型填充自身,应该相当简单。这实际上需要一些学习和实验,但现在它奏效了。在我的示例中,我也为 ListBox 控件做了这个,但它很容易复制到 DropDownList 和其他控件。为了方便重用,我将从枚举中获取值的所有代码都放在了 EnumHelper 类中,可以从您自己的控件中重用。

首先,我创建了 RadioButtonList 的一个子类

Public Class RadioButtonEnum
  Inherits RadioButtonList

然后,我添加了一个 EnumType 属性,您可以在其中指定枚举的类型名称。虽然这对于全局枚举(如 System.DayOfWeek)来说效果很好,但当我尝试使用嵌入式类(例如 MyClass.MyEnum)时却失败了。经过几次测试并在 MSDN 上搜索 GetType 后发现,类中的枚举必须用 '+' 而不是 '.' 来分隔,因此 EnumType 应指定为 MyClass+MyEnum

当从一个模块(当前模块除外)添加枚举时,您还需要指定这一点:例如,如果 MyClass 位于 TestCode.DLL 中,其基础命名空间为 XXX,则枚举类型应读取:XXX.MyClass+MyEnum,TestCode - 有关更多信息,请参阅 http://msdn2.microsoft.com/en-us/library/system.type.assemblyqualifiedname.aspx

命名问题

虽然获取枚举类型的数值和名称相对简单,但代码中枚举值的命名限制非常严格 - 只能使用字母数字字符和下划线。尽管代码中枚举值 SendToCustomer 是可以的,但在用户界面中使用此值并不是一个好习惯。

为了解决这个问题,我添加了一个 FixNames 属性,可以将其设置为 true,将带有下划线或驼峰式命名的枚举值调整为更易读的格式。因此,SendToCustomer 在控件中会变成 Send To Customer

然而,有时我们可能想要其他字符,例如,Urgent! - 或扩展字符集。因此,我增加了查找 Description 属性(System.ComponentModel.DescriptionAttribute)的功能。

实际的枚举值项可以通过 Enum 类型的字段访问,因此 GetEnumNames() 函数会检查是否有任何值具有 Description 属性,并在存在时使用该值。例如:

Public Enum BookRatingWithDescription
  <Description("A <b>great</b> book!")> GreatBook
  <Description("Enjoyable read")> Enjoyable
  <Description("Not bad - ok")> OK
  Poor
  <Description("Where's the shredder?")> Terrible
End Enum

HTML 技巧

一个有用的技巧是 Description 属性的文本可以包含 HTML 标签(这适用于 RadioButtonEnum,但不适用于 ListBoxEnum),如上面第一个枚举值所示。

我也经常使用 XML,所以我添加了使用 XmlEnumAttribute 值的能力,如果存在这些值并且 UseXmlNames 属性设置为 True

示例

为了测试这一点,我包含了一个演示各种功能的网站。这是设计模式下的网页

Design Mode

当页面显示时,控件会自动填充 - 太棒了!

Browser Screenshot

在带有描述的枚举中,第一个项目使用了描述中的 HTML 标签。最后两个示例显示了相同的枚举 - 在第一个实例中 FixNames=False,在第二个实例中 FixNames=True

结论

好了,就这样 - 不再需要将枚举值复制到控件中。希望您觉得有用。

历史

  • 版本 1.0RadioButtonEnumListBoxEnum。虽然是用 VS2005 编写的,但通过将泛型集合的引用更改为 1.x 中支持的类型,应该可以将此代码修改为在 .NET 1.x 上工作。
© . All rights reserved.