Enum里面都是英文,我想通过中文来显示Enum的内容,并且通过中文赋值来改变该Enum的值。
比如
enum GridStyle
    {
        [Description("无")]   
        None,
        [Description("线式")]   
        Line,
        [Description("点式")]   
        DotGrid
    }
在属性下拉框中显示"无,线式,点式"三项,然后选择后改变GridStyle对象的值。
下面是我写的一个类用来实现上述功能class GridStyleTypeEnumConverter : StringConverter
    {
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }        public override GridStyleTypeEnumConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            string[] sGridStyle = new string[Enum.GetValues(typeof(GridStyle)).Length];
            for (int i = 0; i < Enum.GetValues(typeof(GridStyle)).Length; i++)
            {
                GridStyle g = (GridStyle)Enum.GetValues(typeof(GridStyle)).GetValue(i);
                sGridStyle[i] = BaseFun.BaseFunClass.GetEnumDesc(g);//获取并显示该枚举类型的说明,也就是"无,线式,点式"
            }
            return new StandardValuesCollection(sGridStyle);
        }        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
        {
            //return base.GetStandardValuesExclusive(context);
            return true;            // only can choice.
        }        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            foreach (GridStyle gs in Enum.GetValues(typeof(GridStyle)))
            {
                if (BaseFun.BaseFunClass.GetEnumDesc(gs) == value.ToString())//判断枚举说明是否一致,如果一致就返回该枚举值
                {
                    return gs;
                }
            }
            return base.ConvertFrom(context, culture, value);
        }        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if (value is GridStyle)
                return BaseFun.BaseFunClass.GetEnumDesc((GridStyle)value);
            return base.ConvertTo(context, culture, value, destinationType);
        }        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(string))
                return true;
            return base.CanConvertTo(context, destinationType);
        }        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string)) 
                return true;
            return base.CanConvertFrom(context, sourceType);
        }
    }
现在能在属性控件中实现下拉框显示枚举属性并能在选择下拉框时赋值,但是在双击该下拉框时出现转换错误“属性值无效”“类型“System.String”的对象无法转换为类型“Draw.GridStyle”。”。
提示:如果不用这个中文转换,直接是enum类型的话,双击下拉框默认操作是转换到下一个枚举值。
问题:如何才能在用这个中文转换功能时,双击下拉框不发生错误,并能达到转换到下一个枚举值(中文)的功能?

解决方案 »

  1.   

    或者遇到相同情况,大家是怎么处理的。
    有一组英文的Enum值,要在属性控件中用中文显示Enum值,并且再赋值给原Enum。大家是怎么做的?
      

  2.   

    还不如做个字典呢,如果你那样,既要根据反射attribute去找了
      

  3.   

    如果要读取attribute,需要反射。
      

  4.   

    上个月刚折腾了这东西,这段代码给你试试吧。
        class QueryEnumConverter : EnumConverter
        {
            Dictionary<string, object> _descriptionLookup;        public QueryEnumConverter(Type type)
                : base(type)
            {        }        protected string GetEnumDescription(object value)
            {
                EnsureLookup();            foreach (var pair in _descriptionLookup)
                {
                    if (pair.Value.Equals(value)) return pair.Key;
                }            return null;
            }        protected object GetEnumValueFromDescription(string description)
            {            EnsureLookup();            object v;            if (_descriptionLookup.TryGetValue(description, out v))
                    return v;
                else
                    return null;
            }        private void EnsureLookup()
            {
                if (_descriptionLookup == null)
                {
                    _descriptionLookup = new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase);                foreach (var field in EnumType.GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public))
                    {
                        var attr = (DescriptionAttribute)Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute));
                        if (attr != null)
                            _descriptionLookup[attr.Description] = Enum.Parse(EnumType, field.Name);
                    }
                }
            }        public static string GetEnumText(object value)
            {
                if (value == null) return string.Empty;
                Type type = value.GetType();
                if (!type.IsEnum) throw new ArgumentException(type.FullName + " is not a Enum type.");            string name = value.ToString();
                DescriptionAttribute da = (DescriptionAttribute)Attribute.GetCustomAttribute(
                    type.GetField(name, System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public),
                    typeof(DescriptionAttribute));
                if (da != null) return da.Description;
                else return name;
            }        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
            {
                if (destinationType == typeof(string))
                {
                    if (value is string)
                        value = ConvertFrom(context, culture, value);                if (value != null) return GetEnumDescription(value);
                }
                return base.ConvertTo(context, culture, value, destinationType);
            }        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
            {
                if (value is string)
                {
                    string text = (string)value;
                    if (text.Length == 0)
                        return null;                object v = GetEnumValueFromDescription(text);
                    if (v != null) return v;
                }
                
                return base.ConvertFrom(context, culture, value);
            }        public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
            {
                List<object> list = new List<object>();
                list.Add(string.Empty);
                list.AddRange(base.GetStandardValues(context).Cast<object>().Select(o => GetEnumDescription(o) ?? o));
                
                return new StandardValuesCollection(list);
            }
        }
      

  5.   

    谢谢楼上的同志无私的帮助,BaseFun.BaseFunClass.GetEnumDesc(g);我这个函数也是实现了取得Enum的说明文字的。
    我也尝试用了上述代码,但是当我在属性栏中双击Enum中内容时,还是会出现属性值无效”“类型“System.String”的对象无法转换为类型“Draw.GridStyle”。”这个错误。
    你是否也会出现这个问题?
      

  6.   

    也许这个问题无法解决,可能在双击时,默认将Combox中的文本赋值给了Enum,然后造成了这个错误。如果你有解决办法,请通知我,给全分