枚举值的本地化显示与选择

在.NET开发中,枚举(enum)是一种常用的数据类型,用于定义一组命名的常量。然而,直接使用枚举值进行数据绑定时,可能会遇到两个问题:一是枚举值的显示文本可能需要与实际的枚举值有所区别,二是如果需要对应用程序进行本地化,即提供不同文化的翻译界面,直接使用枚举值就无法满足需求。本文将介绍一种利用.NET的TypeConverter机制来解决这些问题的方法。

.NET中,TypeConverter是用于将一种类型的对象转换为另一种类型的对象的内置机制。例如,ListBox控件在显示枚举值时,会首先使用TypeConverter将枚举值转换为字符串。默认情况下,所有枚举类型都使用预定义的EnumConverter类,它将枚举值转换为其精确的字符串表示。幸运的是,可以定义自己的派生TypeConverter类,并将其与枚举类型关联起来。

什么是TypeConverter

.NET中,TypeConverter是用于将一种类型的对象转换为另一种类型的对象的内置机制。例如,ListBox控件在显示枚举值时,会首先使用TypeConverter将枚举值转换为字符串。默认情况下,所有枚举类型都使用预定义的EnumConverter类,它将枚举值转换为其精确的字符串表示。幸运的是,可以定义自己的派生TypeConverter类,并将其与枚举类型关联起来。

自定义TypeConverter

要自定义TypeConverter,需要定义一个继承自TypeConverter的类,并使用System.ComponentModel.TypeConverterAttribute属性将其与枚举类型关联。以下是一个示例:

[TypeConverter(typeof(LocalizedEnumConverter))] public enum SampleEnum { VerySmall, Small, Medium, Large, VeryLarge }

在这个解决方案中,定义了一个自定义的TypeConverter类(LocalizedEnumConverter),它使用项目资源中的本地化字符串将枚举值转换为字符串。

使用代码

示例项目代码包括一个库(Infralution.Localization)和一个单独的测试应用程序。该库定义了一个基础TypeConverter类(ResourceEnumConverter),它使用ResourceManager从编译的RESX文件中读取字符串值。ResourceManager用于查找的构造函数传递给ResourceEnumConverter类。以下是使用此类本地化应用程序中的枚举的简单步骤。

  1. 在应用程序项目中定义一个从ResourceEnumConverter派生的类,传递要用于枚举查找的项目RESX文件的ResourceManager。通常,只需要使用标准项目Properties.Resources:
  2. class LocalizedEnumConverter : Infralution.Localization.ResourceEnumConverter { public LocalizedEnumConverter(Type type) : base(type, Properties.Resources.ResourceManager) { } }
  3. 使用System.ComponentModel.TypeConverterAttribute属性在每个枚举声明上关联此TypeConverter:
  4. [TypeConverter(typeof(LocalizedEnumConverter))] public enum SampleEnum { VerySmall, Small, Medium, Large, VeryLarge }
  5. 打开Properties\Resources.resx文件,在资源编辑器中输入每个枚举值的显示文本。资源名称就是枚举类型名称后跟值(下划线分隔):
  6. 现在准备添加一些本地化的枚举文本值。通过复制Properties\Resources.resx文件到Properties\Resources.fr.resx创建一组法语资源。确保这个新RESX文件的“自定义工具”(在属性窗口中)是空白的,否则会遇到一些奇怪的编译错误。打开Properties\Resources.fr.resx文件,在资源编辑器中输入翻译后的值:
  7. 现在,通过控制面板区域选项将用户区域设置为法语,并运行应用程序。枚举值现在将以法语显示。示例应用程序演示了上述内容,并允许通过从下拉列表中选择来动态设置CurrentThread.CurrentCulture属性:
  8. ResourceEnumConverter类还支持将文本值转换回枚举值。示例应用程序允许通过在文本框中输入值并单击“转换”按钮来测试这一点。

在ASP.NET中本地化枚举

在Windows Forms中,所有标准控件都使用TypeConverters将绑定的数据值转换为显示字符串。不幸的是,出于某种原因,Microsoft在开发ASP.NET控件时没有采用这种方法。ASP.NET控件通常只使用Object.ToString()方法将绑定的数据值转换为文本。这意味着虽然仍然可以定义TypeConverter(如上所述),但它不会默认被ASP.NET控件使用。

为了解决这个问题,在ResourceEnumConverter类中添加了一个静态GetValues方法。该方法使用TypeConverter返回给定枚举类型的KeyValuePair对象列表。Key是枚举值,Value是该枚举的本地化显示文本。要绑定ASP.NET控件,将控件的DataValueField属性设置为Key,DataTextField属性设置为Value。然后绑定控件到GetValues方法返回的列表,如下所示:

protected void Page_Load(object sender, EventArgs e) { _enumListBox.DataSource = LocalizedEnumConverter.GetValues(typeof(SampleEnum)); this.DataBind(); }

标志枚举

Andy Mase指出,原始代码没有处理位字段枚举(使用Flag属性定义)。在这种情况下,枚举值可以是命名枚举值的位组合。枚举还可以定义命名枚举值,这些值是其他命名值的位组合。以下示例中定义了一个All值,它是所有其他值的位组合:

[TypeConverter(typeof(LocalizedEnumConverter))] [Flags] public enum TextStyle : byte { None = 0x0, Bold = 0x1, Italic = 0x2, Underline = 0x4, All = 0xFF }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485