惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

M
MIT News - Artificial intelligence
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
J
Java Code Geeks
G
Google Developers Blog
美团技术团队
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
腾讯CDC
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
The Blog of Author Tim Ferriss
月光博客
月光博客
B
Blog
WordPress大学
WordPress大学
云风的 BLOG
云风的 BLOG
博客园_首页
人人都是产品经理
人人都是产品经理
aimingoo的专栏
aimingoo的专栏
Y
Y Combinator Blog
Jina AI
Jina AI
S
SegmentFault 最新的问题
H
Help Net Security
博客园 - 聂微东
Microsoft Azure Blog
Microsoft Azure Blog
Google DeepMind News
Google DeepMind News

博客园 - MichaeL

【转】单例模式的几种实现方式及其特点 Google Web Toolkit (GWT)是什么? 天下难事,必作于易;天下大事,必作于细。 [工具篇]eclipse 中设置 Java/JSP/JS/HTML/CSS 智能提示 [Liferay 学习笔记]PRUser 中的prUser.setGender("");方法找不到的原因 MessageFormat.format(arg0, arg1)的用途--多语处理 Eclipse Java 开发常见的虚拟内存设置及位置 用微软的Live Writer 离线编写 CNBLOG上的日志 [liferay 学习笔记]搭建liferay的开发环境 [Liferay 学习笔记]liferay portal 安装部署 单反全教程 [原创]HP DV2 1005AU 装机偶得 【原创】从AutoCAD中提取明细栏和标题栏中的数据 Ubuntu 8.04LTS 下中文输入法FCITX的安装与汉字显示方块的解决方法 [原创]偶遇Ubuntu 【原创】C#.Net中对中英文混排的字符串按照指定宽度截取排版 【原创】简单的XML文档读取与操作 【原创】实现Word模板文件中的BookMark允许多次填写修改(含代码) [原创]C#.Net 下的注册表操作(含代码)
【原创】C#.Net 中枚举类型的数据在PropertyGrid控件中的显示...
MichaeL · 2008-06-20 · via 博客园 - MichaeL

摘 要:在程序设计过程中经常会遇到一些数据是以枚举值的形式提供给用户进行选择或查看,通常情况下,枚举数据都是已英文的方式或者便于程序中使用的方式来设 置的。在显示枚举类型的数据是又通常是使用ToString()的方式将枚举数据显示出来,在通过PropertyGrid显示给用户时感觉不是很友好, 很多用户希望能够以中文的方式显示出来。本文就以实例的方式介绍如何在程序中实现PropertyGrid中友好显示的方式,而又不影响Enum类型的数 据在其他地方的使用。

一、引文

    PropertyGrid 中显示对象属性值的方式的特殊设置是可以通过简单的在属性上添加相应的特性标签,比如EditorAttribute(数据编辑控件)、 TypeConverter(数据输入和显示控制)、Category(属性分类)、DescriptionAttribute(属性描述信息)。为了完 成枚举类型的数据显示,这里主要使用的是EditorAttribute和TypeConverter来实现的。首先要创建用于在 PropertyGrid中显示枚举类型数据并允许用户进行选择的控件,然后从UITypeEditor派生一个EnumTypeEditor类,并重写 UITypeEditorEditStyle方法以及EditValue方法用于使得列表中的数据显示为中文,另外还要从TypeConverter派生 一个EnumConverter类,并重写CanConvertTo方法、ConvertTo方法用于属性显示为中文。下面将给出具体的实现方法。

二、实现方法及实验

  1、新建一个枚举类型,每个类型都给指定一个中文的描述特性标签。如下面代码所示:

public enum MarqueeLightShape
{
    [Description("正方形")]
    Square,
    [Description("圆形")]
    Circle,
    [Description("三角形")]
    Triangle,
    [Description("测试")]
    Test
 }

   2、新建一用于显示枚举类型所有数据的列表控件。新建一个用户控件,在其中添加一个ListBox,设置其数据源以及显示成员和值成员。

    public partial class UserCombox : UserControl
    {
        private IWindowsFormsEditorService mEditorService = null;
        private Enum curValue;

        //传入枚举值,以及windowsFormsEditorService控件

        public UserCombox(Enum mValue,IWindowsFormsEditorService editorService)
        {
            InitializeComponent();
            mEditorService = editorService;
            curValue = mValue;   
                if(mValue !=null)
                {
                mCurEnumType = mValue.GetType();
                if(mCurEnumType!=null)
                {
                    if(mCurEnumType.IsEnum)
                    {
                        listBox1.DataSource = ToListForBind(mCurEnumType);
                        listBox1.ValueMember = "Key";
                        listBox1.DisplayMember = "Value";
                        listBox1.SelectedValue = curValue;//根据当前对象的枚举值设置列表中应该选中的项
                        this.Height = listBox1.ItemHeight*listBox1.Items.Count+5;//设置列表控件的高度为列表项能够全部显示出来并且再多5个 像素                       
                    }
                }
                }
        }
        private Type mCurEnumType;
        private Enum mValue;
        public Enum MyValue
        {
            get{
                mValue = this.listBox1.SelectedValue as Enum;
                return mValue;
            }
        }   

     //读取枚举类型的描述信息生成显示数据用的列表数据。   
     public static List<KeyValuePair<Enum, string>> ToListForBind(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (!type.IsEnum)
            {
                throw new ArgumentException("类型必须是枚举型的!", "type");
            }

            List<KeyValuePair<Enum, string>> list = new List<KeyValuePair<Enum, string>>();
            list.Clear();
            Array enumValues = Enum.GetValues(type);

            foreach (Enum value in enumValues)
            {
                list.Add(new KeyValuePair<Enum, string>(value, GetDescription(value)));
            }
            return list;
        }
           #region GetDescription
        /// <summary>
        /// 获取枚举类型值的描述信息.
        /// </summary>
        /// <param name="value">枚举类型<see cref="Enum"/>值</param>
        /// <returns>A string containing the text of the <see cref="DescriptionAttribute"/>.</returns>
        public static  string GetDescription(Enum value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            string description = value.ToString();
            FieldInfo fieldInfo = value.GetType().GetField(description);
            //EnumDescriptionAttribute[] attributes = (EnumDescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(EnumDescriptionAttribute), false);
            DescriptionAttribute[] attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (attributes != null && attributes.Length > 0)
            {
                description = attributes[0].Description;
            }
            else
            {
                description = value.ToString();
            }
            return description;
        }
        #endregion
       
        //用户选择一项后就收起列表控件
        void ListBox1SelectedIndexChanged(object sender, EventArgs e)
        {
            mEditorService.CloseDropDown();
        }
    }

    3、从UITypeEditor派生一个EnumTypeEditor类,并重写UITypeEditorEditStyle方法以及EditValue方法用于使得列表中的数据显示为中文。

public class EnumTypeEditor : UITypeEditor
{

public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;//下拉列表方式,即当在PropertyGrid中选中对象的属性后会显示一个下拉列表按钮
}

//控制编辑时数据的显示方式,并返回该一个值作为属性的值。
public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
{   
IWindowsFormsEditorService editorService  = null;
    if (provider != null)
    {
        editorService =provider.GetService(
            typeof(IWindowsFormsEditorService)) 
            as IWindowsFormsEditorService;
    }
    if (editorService != null)
    {
        UserCombox mComBox = new UserCombox((Enum)value,editorService); //创建显示枚举类型数据的中文描述的控件
        editorService.DropDownControl(mComBox);//展开下拉列表在下拉区域显示传入的控件
        value = mComBox.MyValue;//将列表控件中用于选定的值赋值给需要返回的Value
    }
    return value;
}
}

4、从TypeConverter派生一个EnumConverter类,并重写CanConvertTo方法、ConvertTo方法用于属性显示为中文

internal class EnumConverter : TypeConverter
 {
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return true;
    }
    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
       
        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!";
    }
 }

5、给需要显示中文描述的对象属性添加特性标签。

private MarqueeLightShape mTestEnum ;
[DescriptionAttribute("Test 枚举值."),
EditorAttribute(typeof(EnumTypeEditor), typeof(System.Drawing.Design.UITypeEditor)),
]
[TypeConverter(typeof(EnumConverter))]
public MarqueeLightShape TestEnum
{
get { return mTestEnum; }
set { mTestEnum = value; }
}

6、显示效果图

其他可参考的资料:http://msdn.microsoft.com/zh-cn/library/ms171840(VS.80).aspx