关于enum类型的本地化的一种方法探索:

enum类型是一种符号标记,便于开发者在程序编码中使用,从而避免数字类的状态标记。正是因为其主要是用于代码层面,所以设计之初就没有考虑过本地化的支持。但是,在很多情况下,我们都需要绑定enum类型到一个类似于ComboBox的控件以提供用户选择项,这个时候,本地化就显得必要了。当然,enum的本地化方式多种多样,本文试图探讨一种利用DataAnnotation的方法间接实现本地化。

首先,定义一个DeviceType类型,并使用DataAnnotation方式标记enum类型的本地化资源(具体请参考DataAnnotation),示例中提供了英文和中文的两个资源文件,默认英文。

    public enum DeviceType
    {
        [Display(Name="laptop",ResourceType=typeof(ApplicationResource))]
        LapTop,
        [Display(Name = "desktop", ResourceType = typeof(ApplicationResource))]
        Desktop,
        [Display(Name = "mobile", ResourceType = typeof(ApplicationResource))]
        MobilePhone,
        [Display(Name = "router", ResourceType = typeof(ApplicationResource))]
        Router,
        [Display(Name = "fax", ResourceType = typeof(ApplicationResource))]
        Fax
    }

 

 然后,编写一个扩展方法,用于将enum类型转换为Dictionary<int,string>类型的字典,其中int为enum项的常量值,string为该enum项的本地化字符串,具体如下:

    public static class EnumExtension
    {
        public static Dictionary<int, string> ToDictionary(this Type enumType)
        {
            if (!enumType.IsEnum)
            {
                throw new ArgumentException("Type must be enum!");
            }

            Dictionary<int, string> enumStrings = new Dictionary<int, string>();

            //查看枚举类型中的每项,如果有DisplayAttribute,则使用其本地化的字符串资源,否则,直接使用枚举的默认名称
            int[] enumValues = Enum.GetValues(enumType) as int[];
            foreach (int v in enumValues)
            {
                string enumName = Enum.GetName(enumType, v);
                DisplayAttribute[] attributes = enumType.GetField(enumName).GetCustomAttributes(typeof(DisplayAttribute), false) as DisplayAttribute[];
                if (attributes == null || attributes.Length < 1)
                {
                    enumStrings.Add(v, enumName);
                }
                else
                {
                    ResourceManager mgr = new ResourceManager(attributes[0].ResourceType);
                    enumStrings.Add(v,mgr.GetString(attributes[0].Name));
                }
            }

            return enumStrings;
        }
    }

然后,在任何需要枚举类型的控件上直接绑定ToDictionary方法返回的字典即可。如下例中在Silverlight中:

 

        public MainPage()
        {
            InitializeComponent();
            comboBox.ItemsSource = typeof(DeviceType).ToDictionary();
            comboBox.SelectedIndex = 0;
            comboBox.DisplayMemberPath = "Value";
            comboBox.SelectedValuePath = "Key";
        }

这样,在设置了线程的语言文化Thread.CurrentCulture后即可实现枚举类型的本地化。

 

 

posted @ 2013-05-08 16:40  kennywangjin  阅读(1551)  评论(2编辑  收藏  举报