PropertyGrid中的枚举显示为中文

来源:互联网 发布:淘宝摄影布光 编辑:程序博客网 时间:2024/05/17 12:56

 

在系统开发中,经常会使用PropertyGrid来修改或者展示某个对象的属性,如果类中定义了枚举,在展现的时候默认会展示枚举的项或者枚举值,但是这并不是我们想要的。用户使用的时候并不清楚该项代表的意思。之前介绍过枚举显示中文的一篇文章,大家可以看下,枚举显示中文。

想要的效果:

在PropertyGrid中枚举显示中,又比较复杂一些。PropertyGrid显示复杂属性需要TypeConverter,也就是一个转换器,可以对其进行设置,显示我们想要的格式、内容。现有技术PropertyGrid枚举显示中文,有一些利用了绑定自定义控件,有一些绑定自定义的IList对象。但是,每个枚举都要建立自己的TypeConverter,如果在架构设计中,一般都是分层实现,这样的横跨直接影响了分层结构,破坏系统的原本。有没有一种更好的办法来实现呢?本文也就这一问题进行了研究。

本文的实现原理:

在TypeConverter中对枚举类型进行转换,但是这个TypeConverter针对的所有的枚举对象,所有的枚举转换器都可以采用此接口,在枚举显示的时候调用TypeConverter,通过反射获得相对应的枚举描述。这样所有的枚举就只定义一个TypeConverter。也就解决上述问题。

具体事例:

1、定义枚举:在枚举中加入描述信息,作为我们需要显示的信息

 

public enum PKGenerator    {        /// <summary>        /// 根据主键类型自动生成主键        /// </summary>        [Description("自动生成")]        AutoGenerate=0,        /// <summary>        /// 自定义主键        /// </summary>        [Description("自定义")]        User_Defined =1,        /// <summary>        /// 由外面传入        /// </summary>        [Description("外部传入")]        Outer =2    }}


2、定义TypeConverter,对枚举和选择进行转换

/// <summary>    /// 枚举转换器    /// 用此类之前,必须保证在枚举项中定义了Description    /// </summary>    public class EnumConverter : ExpandableObjectConverter    {        /// <summary>        /// 枚举项集合        /// </summary>        Dictionary<object, string> dic;        /// <summary>        /// 构造函数        /// </summary>        public EnumConverter()        {            dic = new Dictionary<object, string>();        }        /// <summary>        /// 加载枚举项集合        /// </summary>        /// <param name="context"></param>        private void LoadDic(ITypeDescriptorContext context)        {            dic = GetEnumValueDesDic(context.PropertyDescriptor.PropertyType);        }        /// <summary>        /// 是否可从来源转换        /// </summary>        /// <param name="context"></param>        /// <param name="sourceType"></param>        /// <returns></returns>        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)        {            if (sourceType == typeof(string))                return true;            return base.CanConvertFrom(context, sourceType);        }        /// <summary>        /// 从来源转换        /// </summary>        /// <param name="context"></param>        /// <param name="culture"></param>        /// <param name="value"></param>        /// <returns></returns>        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)        {            if (value is string)            {                //如果是枚举                if (context.PropertyDescriptor.PropertyType.IsEnum)                {                    if (dic.Count <= 0)                        LoadDic(context);                    if (dic.Values.Contains(value.ToString()))                    {                        foreach (object obj in dic.Keys)                        {                            if (dic[obj] == value.ToString())                            {                                return obj;                            }                        }                    }                }            }            return base.ConvertFrom(context, culture, value);        }        /// <summary>        /// 是否可转换        /// </summary>        /// <param name="context"></param>        /// <param name="destinationType"></param>        /// <returns></returns>        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)        {            return true;        }        /// <summary>        ///         /// </summary>        /// <param name="context"></param>        /// <returns></returns>        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)        {            return true;        }        /// <summary>        ///         /// </summary>        /// <param name="context"></param>        /// <returns></returns>        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)        {            return true;        }        /// <summary>        ///         /// </summary>        /// <param name="context"></param>        /// <returns></returns>        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)        {            //ListAttribute listAttribute = (ListAttribute)context.PropertyDescriptor.Attributes[typeof(ListAttribute)];            //StandardValuesCollection vals = new TypeConverter.StandardValuesCollection(listAttribute._lst);            //Dictionary<object, string> dic = GetEnumValueDesDic(typeof(PKGenerator));            //StandardValuesCollection vals = new TypeConverter.StandardValuesCollection(dic.Keys);            if (dic == null || dic.Count <= 0)                LoadDic(context);            StandardValuesCollection vals = new TypeConverter.StandardValuesCollection(dic.Keys);            return vals;        }        /// <summary>        ///         /// </summary>        /// <param name="context"></param>        /// <param name="culture"></param>        /// <param name="value"></param>        /// <param name="destinationType"></param>        /// <returns></returns>        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)        {            //DescriptionAttribute.GetCustomAttribute(            //EnumDescription            //List<KeyValuePair<Enum, string>> mList = UserCombox.ToListForBind(value.GetType());            //foreach (KeyValuePair<Enum, string> mItem in mList)            //{            //    if (mItem.Key.Equals(value))            //    {            //        return mItem.Value;            //    }            //}            //return "Error!";            //绑定控件            //            FieldInfo fieldinfo = value.GetType().GetField(value.ToString());            //Object[] objs = fieldinfo.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), false);            //if (objs == null || objs.Length == 0)            //{            //    return value.ToString();            //}            //else            //{            //    System.ComponentModel.DescriptionAttribute da = (System.ComponentModel.DescriptionAttribute)objs[0];            //    return da.Description;            //}            if (dic.Count <= 0)                LoadDic(context);            foreach (object key in dic.Keys)            {                if (key.ToString() == value.ToString() || dic[key] == value.ToString())                {                    return dic[key].ToString();                }            }            return base.ConvertTo(context, culture, value, destinationType);        }        /// <summary>        /// 记载枚举的值+描述        /// </summary>        /// <param name="enumType"></param>        /// <returns></returns>        public Dictionary<object, string> GetEnumValueDesDic(Type enumType)        {            Dictionary<object, string> dic = new Dictionary<object, string>();            FieldInfo[] fieldinfos = enumType.GetFields();            foreach (FieldInfo field in fieldinfos)            {                if (field.FieldType.IsEnum)                {                    Object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);                    if (objs.Length > 0)                    {                        dic.Add(Enum.Parse(enumType, field.Name), ((DescriptionAttribute)objs[0]).Description);                    }                }            }            return dic;        }    }


3、属性使用TypeConverter:

 

public class EntityKey    {        [Description("主键生成方式"), DisplayName("主键生成方式")]        [TypeConverter(typeof(EnumConverter))]        public PKGenerator PKGenerator        {            get;            set;        }    }


 

具体效果如下图: