240
一线老司机

使枚举类型的选项在VS的属性窗里显示为中文

     我们自己做的组件,一般希望它的属性在设计时能够在属性窗里显示为中文,可以在属性上添加System.ComponentModel.DisplayNameAttribute标注达到这个目的。但是,枚举的选项如何以中文的形式显示在属性窗里呢?

     假设我们有如下枚举:

   1: public enum MyEnum
   2: {    
   3:     A,   
   4:     B
   5: }

     在某个组件里有一个MyEnum类型的属性,如下:

   1: [DisplayName("我的枚举")]
   2:  public MyEnum MyEnum
   3:  {
   4:      get;set;
   5:  }

     在设计时把这个组件拖到设计器中,发现属性窗中出现了“我的枚举”这个属性,但选项是A和B,如何让它们示为“选项一”和“选项二”呢?这就需要利用到TypeConverter了,因为PropertyGrid利用TypeConverter来显示枚举的选项的。另外,为了使扩展性更好,我们还需要DescriptionAttribute.

     继承System.ComponentModel.EnumConverter,实现自己的Converter,如下:

   1: public class MyEnumConverter : EnumConverter
   2: {
   3:     private IDictionary<object, string> dic;
   4:     private IDictionary<string, object> dic2;
   5:     private readonly Type type = typeof(MyEnum);
   6:  
   7:     public MyEnumConverter()
   8:         : base(typeof(MyEnum))
   9:     {
  10:     }
  11:     
  12:  
  13:     public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
  14:     {
  15:         if(value is string)
  16:         {
  17:             if(dic2 != null && dic2.ContainsKey(value as string))
  18:             {
  19:                 return dic2[value as string];
  20:             }
  21:         }
  22:         return base.ConvertFrom(context, culture, value);
  23:     }
  24:  
  25:     public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
  26:     {
  27:         if(destinationType == typeof(string))
  28:         {
  29:             if(dic == null)
  30:             {
  31:                 dic = new Dictionary<object, string>();
  32:                 dic2 = new Dictionary<string, object>();
  33:                 Type reflectionType = TypeDescriptor.GetReflectionType(this.type);
  34:                 if (reflectionType == null)
  35:                 {
  36:                     reflectionType = this.type;
  37:                 }
  38:                 FieldInfo[] fields = reflectionType.GetFields(BindingFlags.Public | BindingFlags.Static);
  39:                 ArrayList list = null;
  40:                 if ((fields != null) && (fields.Length > 0))
  41:                 {
  42:                     list = new ArrayList(fields.Length);
  43:                 }
  44:                 if (list != null)
  45:                 {
  46:                     foreach (FieldInfo info in fields)
  47:                     {
  48:                         object fieldValue = info.GetValue(info);
  49:                         string desc = fieldValue.ToString();
  50:                         DescriptionAttribute descriptionAttribute = null;
  51:                         foreach (DescriptionAttribute a in info.GetCustomAttributes(typeof(DescriptionAttribute), false))
  52:                         {
  53:                             descriptionAttribute = a;
  54:                             break;
  55:                         }
  56:                         if (descriptionAttribute != null)
  57:                         {
  58:                             desc = descriptionAttribute.Description;
  59:                         }
  60:                         dic[fieldValue] = desc;
  61:                         dic2[desc] = fieldValue;
  62:                     }
  63:                 }
  64:             }
  65:             return dic[value];
  66:         }
  67:         
  68:         return base.ConvertTo(context, culture, value, destinationType);
  69:     }
  70: }

     然后修改MyEnum,如下:

   1: public enum MyEnum
   2: {
   3:     [Description("选项一")]
   4:     A,
   5:     [Description("选项二")]
   6:     B
   7: }

     并且修改组件里的属性,加入TypeConverterAttribute,如下:

   1: [DisplayName("我的枚举")]
   2: [TypeConverter(typeof(MyEnumConverter))]
   3: public MyEnum MyEnum
   4: {
   5:     get;
   6:     set;
   7: }

     这样,就可以以中文的形式在属性窗里显示枚举的选项了,如下图:

     image

posted @ 2010-06-12 13:54  明年我18  阅读(1920)  评论(3编辑  收藏  举报