System.Windows.Forms.PropertyGrid的使用

PropertyGrid 控件简介

.NET 框架 PropertyGrid 控件是 Visual Studio .NET 属性浏览器的核心。PropertyGrid 控件显示对象或类型的属性,并主要通过使用反射来检索项目的属性。当我们创建了一个类编译之后就生成了类的Metadata,元数据。PropertyGrid 就是使用反射来展示和修改类的公共属性的,就是public标识的属性。但凡成熟的软件都是使用配置来满足不同场景或者客户的需求,就是使用参数开关的形式。PropertyGrid 代表了主流的配置界面,对于实施培训的技术支持人员比较人性化。现在就来分享一下使用心得。

SelectedObject

PropertyGrid 的方法SelectedObject是获取或设置在网格中显示属性的对象。是使用PropertyGrid显示对象的最重要方法。

实际用例截图

使用的要点

  • 1)属性值如果是枚举类型,则设置改属性时自动生成下拉框和填充选择值。
  • 2)属性可自定义分类
  • 3)属性可注释和说明
  • 4)属性设置可自定义属性类型
  • 5)如果需要隐藏属性不在PropertyGrid里显示出来,可以在类的属性上标记[Browsable(false)] 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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"接口的类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
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需要维护的类上作自定义属性的标记。

1
2
3
4
5
6
7
8
9
10
11
12
public class BarcodeElementNode : PropertyBase, IElementNodeData, INotifyPropertyChanged
 
    {
        private Point location;
        [ChnProperty("位置", "节点元素的在模板里的位置的坐标,鼠标选中节点即可以移动位置。")]
        [Category("通用属性")]
        public Point Location
        {
            get { return location; }
            set { location = value; }
        }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/// <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; }
        }
    }

 

  

好了。收工,不写点啥心慌。但是写好需要花很多时间。只是坚持一下吧

posted @   数据酷软件  阅读(560)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示