PropertyGrid控件开发总结一

 新项目开发涉及到了窗体控件的使用。其中,尤以propertyGrid为重。被众多先辈誉为RAD开发的重要工具。Rapid application development (RAD) is a term originally used to describe a software development process introduced by James Martin in 1991. Martin's methodology involves iterative development and the construction of prototypes。以上英文简介来源于http://en.wikipedia.org/wiki/Rapid_application_development

本次开发到目前为止,涉及到了以下问题:

1、信息的本地化

2、属性类的动态隐藏

3、属性编辑器的定制

4、属性排序方式

5、属性值的验证

6、自定义类型复合属性的表示

针对以上问题,接下来讨论其解决方案。

1、描述信息的本地化

首先、信息本地化的实现是通过system.ComponentModel名空间下的属性类(Attribute 类)来实现。本类皆以Attribute结尾,提供了属性的描述[Description(String s)]、类别[Category(String s)]、显示名称[DisplayName(String s)]、可写性[ReadOnly(bool bo)]、显示性[Browsable(bool bo)]。以属性描述为例示例如下:

private int a;//a不是传入propertyGrid控件的属性,其get/set方法名才是默认属性名。

[Description(descriptString)]//descriptString 将描述信息传给控件作为属性A的描述,通过继承该类

public int A{}                      //可以将string型参数descriptString作为key,根据系统语言环境参数进行``````````````````````````````````//查值,以实现本地化。

.net中所有基本类型都有相对应的编辑器,这导致Enum类型的属性值显示的是内部enum值,并非用户容易理解的信息,对这一类型的本地化工作相对复杂。由于enum下的成员不是作为属性显示所以他的[DisplayName(String s)]无用武之地。而信息的表示是由控件最终完成,所以可以绕开属性设定,通过属性的编辑器实现枚举值的信息本地化。示例如下:(代码及思路来源于网络,感谢先辈们)

public enum Test//测试枚举类
    {
        [LocalizeDescription("ENUM_A")]
        aaaa = 0,
        [LocalizeDescription("ENUM_B")]
        bbbb,
        [LocalizeDescription("ENUM_C")]
        cccc
    }

class ...//测试类,含Test枚举类型属性tTest

{

        private Test tTest;

        ...

        [EditorAttribute(typeof(EnumTypeEditor), typeof(System.Drawing.Design.UITypeEditor)), ]
        [TypeConverter(typeof(EnumConverter))]
        public Test TTest
        {
            get { return test; }
            set { test = value; }
        }

...

}

//枚举类型编辑器

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
                value = mComBox.MyValue;
                
            }
            return value;
        }
    }

//枚举类型的类型转换器 ,实现枚举值到用户可视信息的转换  

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!";
        }
    }

 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;
                        //设置列表控件的高度为列表项能够全部显示出来并且再多5个像素 
                        this.Height = listBox1.ItemHeight * listBox1.Items.Count + 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();
        }
    }

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值