.NET 框架 PropertyGrid 控件是 Visual Studio .NET 属性浏览器的核心。PropertyGrid 控件显示对象或类型的属性,并主要通过使用反射来检索项目的属性。当我们创建了一个类编译之后就生成了类的Metadata,元数据。PropertyGrid 就是使用反射来展示和修改类的公共属性的,就是public标识的属性。但凡成熟的软件都是使用配置来满足不同场景或者客户的需求,就是使用参数开关的形式。PropertyGrid 代表了主流的配置界面,对于实施培训的技术支持人员比较人性化。现在就来分享一下使用心得。
SelectedObject
PropertyGrid 的方法SelectedObject是获取或设置在网格中显示属性的对象。是使用PropertyGrid显示对象的最重要方法。
实际用例截图
使用的要点:
- 1)属性值如果是枚举类型,则设置改属性时自动生成下拉框和填充选择值。
- 2)属性可自定义分类
- 3)属性可注释和说明
- 4)属性设置可自定义属性类型
- 5)如果需要隐藏属性不在PropertyGrid里显示出来,可以在类的属性上标记[Browsable(false)]
private string _动态内容; [Description(@"格式:{PropertyName[(Start[,Length])]}[&Blank[(Length)]]&{PropertyName[(Start[,Length])]} PropertyName:动态属性里的选项 Start:动态属性对应内容的开始位置 Length:截取内容的长度 Blank:空格 Length:空格的个数 &:为分隔符 设置此内容的时候,请务必小心,设置时系统不检测其值的合法性,在执行的时候可能会报错"), Category("表达式")] [XmlAttribute("动态内容")] public string 动态内容 { get { return _动态内容; } set { _动态内容 = value; NotifyPropertyChanged("动态内容"); } }
要更改某些属性的显示方式,您可以对这些属性应用不同的特性。特性是用于为类型、字段、方法和属性等编程元素添加批注的声明标记,在运行时可以使用反射对其进行检索。下面列出了其中的一部分:
DescriptionAttribute - 设置显示在属性下方说明帮助窗格中的属性文本。这是一种为活动属性(即具有焦点的属性)提供帮助文本的有效方法。
CategoryAttribute - 设置属性在网格中所属的类别。当您需要将属性按类别名称分组时,此特性非常有用。如果没有为属性指定类别,该属性将被分配给杂项 类别。可以将此特性应用于所有属性。
BrowsableAttribute – 表示是否在网格中显示属性。此特性可用于在网格中隐藏属性。默认情况下,公共属性始终显示在网格中。
ReadOnlyAttribute – 表示属性是否为只读。此特性可用于禁止在网格中编辑属性。默认情况下,带有 get 和 set 访问函数的公共属性在网格中是可以编辑的。
DefaultValueAttribute – 表示属性的默认值。如果希望为属性提供默认值,然后确定该属性值是否与默认值相同,则可使用此特性。可以将此特性应用于所有属性。
DefaultPropertyAttribute – 表示类的默认属性。在网格中选择某个类时,将首先突出显示该类的默认属性。
自定义PropertyGrid属性 请参考文章:http://blog.csdn.net/jjhua/article/details/23100143.
PropertyGrid显示英文字符为中文
PropertyGrid显示英文字符为中文,需要自定义属性和实现一个自定义的PropertyDescriptor子类,还有一个实现了"ICustomTypeDescriptor"接口的类。
namespace GDIPrinterDriver { public delegate void PropertyChanged(object Value); /// <summary> /// 主要是实现中文化属性显示 /// </summary> public class PropertyBase : ICustomTypeDescriptor { AttributeCollection ICustomTypeDescriptor.GetAttributes() { return TypeDescriptor.GetAttributes(this, true); } string ICustomTypeDescriptor.GetClassName() { return TypeDescriptor.GetClassName(this, true); } string ICustomTypeDescriptor.GetComponentName() { return TypeDescriptor.GetComponentName(this, true); } TypeConverter ICustomTypeDescriptor.GetConverter() { return TypeDescriptor.GetConverter(this, true); } EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() { return TypeDescriptor.GetDefaultEvent(this, true); } PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() { return null; } object ICustomTypeDescriptor.GetEditor(Type editorBaseType) { return TypeDescriptor.GetEditor(this, editorBaseType, true); } EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { return TypeDescriptor.GetEvents(this, true); } EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) { return TypeDescriptor.GetEvents(this, attributes, true); } PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() { return ((ICustomTypeDescriptor)this).GetProperties(new Attribute[0]); } PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) { ArrayList props = new ArrayList(); Type thisType = this.GetType(); PropertyInfo[] pis = thisType.GetProperties(); foreach (PropertyInfo p in pis) { if (p.DeclaringType == thisType || p.PropertyType.ToString() == "System.Drawing.Color") { //判断属性是否显示 BrowsableAttribute Browsable = (BrowsableAttribute)Attribute.GetCustomAttribute(p, typeof(BrowsableAttribute)); if (Browsable != null) { if (Browsable.Browsable == true || p.PropertyType.ToString() == "System.Drawing.Color") { PropertyStub psd = new PropertyStub(p, attributes); props.Add(psd); } } else { PropertyStub psd = new PropertyStub(p, attributes); props.Add(psd); } } } PropertyDescriptor[] propArray = (PropertyDescriptor[])props.ToArray(typeof(PropertyDescriptor)); return new PropertyDescriptorCollection(propArray); } object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) { return this; } } /// <summary> /// 自定义属性拦截器 /// </summary> public class PropertyStub : PropertyDescriptor { PropertyInfo info; public PropertyStub(PropertyInfo propertyInfo, Attribute[] attrs) : base(propertyInfo.Name, attrs) { info = propertyInfo; } public override Type ComponentType { get { return info.ReflectedType; } } public override bool IsReadOnly { get { return info.CanWrite == false; } } public override Type PropertyType { get { return info.PropertyType; } } public override bool CanResetValue(object component) { return false; } public override object GetValue(object component) { try { return info.GetValue(component, null); } catch { return null; } } public override void ResetValue(object component) { } public override void SetValue(object component, object value) { info.SetValue(component, value, null); } public override bool ShouldSerializeValue(object component) { return false; } //通过重载下面这个属性,可以将属性在PropertyGrid中的显示设置成中文 public override string DisplayName { get { if (info != null) { ChnPropertyAttribute uicontrolattibute = (ChnPropertyAttribute)Attribute.GetCustomAttribute(info, typeof(ChnPropertyAttribute)); if (uicontrolattibute != null) return uicontrolattibute.PropertyName; else { return info.Name; } } else return ""; } } public override string Description { get { if (info != null) { ChnPropertyAttribute uicontrolattibute = (ChnPropertyAttribute)Attribute.GetCustomAttribute(info, typeof(ChnPropertyAttribute)); if (uicontrolattibute != null) return uicontrolattibute.PropertyDescription; } return string.Empty; } } } }
然后在PropertyGrid需要维护的类上作自定义属性的标记。
public class BarcodeElementNode : PropertyBase, IElementNodeData, INotifyPropertyChanged { private Point location; [ChnProperty("位置", "节点元素的在模板里的位置的坐标,鼠标选中节点即可以移动位置。")] [Category("通用属性")] public Point Location { get { return location; } set { location = value; } } }
/// <summary> /// 中文方式自定义属性标识 /// </summary> public class ChnPropertyAttribute : Attribute { private string _PropertyName; private string _PropertyDescription; public ChnPropertyAttribute(string Name, string Description) { _PropertyName = Name; _PropertyDescription = Description; } public ChnPropertyAttribute(string Name) { _PropertyName = Name; _PropertyDescription = ""; } public string PropertyName { get { return _PropertyName; } } public string PropertyDescription { get { return _PropertyDescription; } } }
好了。收工,不写点啥心慌。但是写好需要花很多时间。只是坚持一下吧