PropertyGrid—添加EventTab

零.引言

  前面一篇文章介绍了如何在PropertyGrid中添加属性Tab,本文主要介绍如何添加事件选项卡。事件在许多对象中都有,尤其是在控件中,如何让对象的事件在PropertyGrid中显示出来呢,本文将进行简单的说明。

一.回顾添加属性Tab

  在上篇文章中详细的讲解了如何添加属性Tab,这里简单回顾一下:

  1.新建一个Tab类并继承于PropertyTab。

  2.重写TabName和Bitmap属性以及GetProperties方法。

  3.给特定类添加PropertyTab特性或将自定义Tab类添加到PropertyGrid的PropertyTabs集合中。

  三步就可以完成了,添加EventTab与此类似,现在问题的关键在于我们要显示的是事件,而GetProperties方法只能返回属性集合(PropertyDescriptorCollection)。怎么办呢,很简单,我们把事件封装成PropertyDescriptor,再返回就行了。

二. 添加EventTab

  GetProperties方法只能返回属性集合。那我们就把事件封装成PropertyDescriptor。首先定义一个封装事件的类,该类继承于PropertyDescriptor:

  

 1     class EventWrapper : PropertyDescriptor
 2     {
 3         string name; //名字
 4         public EventWrapper(string name)
 5             : base(name, null)
 6         {
 7             this.name = name;
 8         }
 9
10         public override bool CanResetValue(object component)
11         {
12             return true;
13         }
14
15         public override string DisplayName
16         {
17             get
18             {
19                 return name;
20             }
21         }
22
23         public override string Description
24         {
25             get
26             {
27                 return string.Format("{0} description", name);
28             }
29         }
30
31         public override bool IsReadOnly
32         {
33             get { return false; }
34         }
35
36         public override string Name
37         {
38             get
39             {
40                 return "fs2_" + name;
41             }
42         }
43
44         public override Type ComponentType
45         {
46             get { throw new NotImplementedException(); }
47         }
48
49         public override object GetValue(object component)
50         {
51             //do something
52             return "";
53         }
54
55         public override Type PropertyType
56         {
57             get { return typeof(string); }
58         }
59
60         public override void ResetValue(object component)
61         {
62             throw new NotImplementedException();
63         }
64
65         public override void SetValue(object component, object value)
66         {
67             //do something
68         }
69
70         public override bool ShouldSerializeValue(object component)
71         {
72             return false;
73         }
74     }

  继承PropertyDescriptor时,需要重写一些属性和方法。封装类中,我们定义了一个name,用来保存事件的名称。好了,现在EventWrapper是从PropertyDescriptor继承而来,可以作为GetProperties方法的返回类型了。

  接下来像前一篇文章一样定义一个EventsTab选型卡类:

  

 1 public class EventsTab : System.Windows.Forms.Design.PropertyTab
 2     {
 3         [BrowsableAttribute(true)]
 4         // This string contains a Base-64 encoded and serialized example property tab image.
 5         private string img = "AAEAAAD/////AQAAAAAAAAAMAgAAAFRTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0xLjAuMzMwMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA9gAAAAJCTfYAAAAAAAAANgAAACgAAAAIAAAACAAAAAEAGAAAAAAAAAAAAMQOAADEDgAAAAAAAAAAAAD///////////////////////////////////9ZgABZgADzPz/zPz/zPz9AgP//////////gAD/gAD/AAD/AAD/AACKyub///////+AAACAAAAAAP8AAP8AAP9AgP////////9ZgABZgABz13hz13hz13hAgP//////////gAD/gACA/wCA/wCA/wAA//////////+AAACAAAAAAP8AAP8AAP9AgP////////////////////////////////////8L";
 6
 7         public override System.ComponentModel.PropertyDescriptorCollection GetProperties(object component, Attribute[] attributes)
 8         {
 9             //Return list of known events
10             EventDescriptorCollection events_info;
11             if (attributes == null)
12                 events_info = TypeDescriptor.GetEvents(component);
13             else
14                 events_info = TypeDescriptor.GetEvents(component, attributes);
15             //封装事件
16             var events = new PropertyDescriptor[events_info.Count];
17             for (int i = 0; i < events_info.Count; i++)
18                 events[i] = new EventWrapper(events_info[i].Name);
19
20             return new PropertyDescriptorCollection(events);
21         }
22
23         public override string TabName
24         {
25             get { return "Events"; }
26         }
27
28         public override System.Drawing.Bitmap Bitmap
29         {
30             get
31             {
32                 Bitmap bmp = new Bitmap(DeserializeFromBase64Text(img));
33
34                 return bmp;
35             }
36         }
37
38         private Image DeserializeFromBase64Text(string text)
39         {
40             Image img = null;
41             byte[] memBytes = Convert.FromBase64String(text);
42             IFormatter formatter = new BinaryFormatter();
43             MemoryStream stream = new MemoryStream(memBytes);
44             img = (Image)formatter.Deserialize(stream);
45             stream.Close();
46             return img;
47         }
48 }

  唯一的不同是在Getproperties方法中,我们先获取对象的事件信息,再将其封装为我们定义的事件封装类,并返回。

  现在要做的就是将我们定义的EventsTab类型添加到PropertyGrid控件的PropertyTabs集合中,将MyControl对象赋值给PropertyGrid控件的SelectedObject属性,运行程序,就可以看到MyControl对象的事件列表,效果如下:

  

  可见,事件都列出来了。

三.完整代码

  下面是完整代码:

  

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Windows.Forms;
  6 using System.Windows.Forms.Design;
  7 using System.ComponentModel;
  8 using System.ComponentModel.Design;
  9 using System.Drawing;
 10 using System.IO;
 11 using System.Runtime.Serialization;
 12 using System.Runtime.Serialization.Formatters.Binary;
 13
 14 namespace TestAddTab
 15 {
 16     //控件类
 17     //[PropertyTabAttribute(typeof(MyPropertyTab), PropertyTabScope.Component)]
 18     public class MyControl : System.Windows.Forms.UserControl
 19     {
 20         private double _angle = 90;
 21
 22         public MyControl()
 23         {
 24         }
 25
 26         [BrowsableAttribute(true)]
 27         [Category("角度")]
 28         public double Angle
 29         {
 30             get
 31             { return _angle; }
 32             set
 33             { _angle = value; }
 34         }
 35
 36
 37         protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
 38         {
 39             e.Graphics.DrawString("The Angle is " + _angle, this.Font, Brushes.Red, 0, 0);
 40         }
 41     }
 42
 43     public class EventsTab : System.Windows.Forms.Design.PropertyTab
 44     {
 45         [BrowsableAttribute(true)]
 46         // This string contains a Base-64 encoded and serialized example property tab image.
 47         private string img = "AAEAAAD/////AQAAAAAAAAAMAgAAAFRTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0xLjAuMzMwMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA9gAAAAJCTfYAAAAAAAAANgAAACgAAAAIAAAACAAAAAEAGAAAAAAAAAAAAMQOAADEDgAAAAAAAAAAAAD///////////////////////////////////9ZgABZgADzPz/zPz/zPz9AgP//////////gAD/gAD/AAD/AAD/AACKyub///////+AAACAAAAAAP8AAP8AAP9AgP////////9ZgABZgABz13hz13hz13hAgP//////////gAD/gACA/wCA/wCA/wAA//////////+AAACAAAAAAP8AAP8AAP9AgP////////////////////////////////////8L";
 48
 49
 50         public override System.ComponentModel.PropertyDescriptorCollection GetProperties(object component, Attribute[] attributes)
 51         {
 52             //Return list of known events
 53             EventDescriptorCollection events_info;
 54             if (attributes == null)
 55                 events_info = TypeDescriptor.GetEvents(component);
 56             else
 57                 events_info = TypeDescriptor.GetEvents(component, attributes);
 58
 59             var events = new PropertyDescriptor[events_info.Count];
 60             for (int i = 0; i < events_info.Count; i++)
 61                 events[i] = new EventWrapper(events_info[i].Name);
 62
 63             return new PropertyDescriptorCollection(events);
 64         }
 65
 66         public override string TabName
 67         {
 68             get { return "Events"; }
 69         }
 70
 71         public override System.Drawing.Bitmap Bitmap
 72         {
 73             get
 74             {
 75                 Bitmap bmp = new Bitmap(DeserializeFromBase64Text(img));
 76                 return bmp;
 77             }
 78         }
 79
 80         private Image DeserializeFromBase64Text(string text)
 81         {
 82             Image img = null;
 83             byte[] memBytes = Convert.FromBase64String(text);
 84             IFormatter formatter = new BinaryFormatter();
 85             MemoryStream stream = new MemoryStream(memBytes);
 86             img = (Image)formatter.Deserialize(stream);
 87             stream.Close();
 88             return img;
 89         }
 90     }
 91
 92     class EventWrapper : PropertyDescriptor
 93     {
 94         string name;
 95         public EventWrapper(string name)
 96             : base(name, null)
 97         {
 98             this.name = name;
 99         }
100
101         public override bool CanResetValue(object component)
102         {
103             return true;
104         }
105
106         public override string DisplayName
107         {
108             get
109             {
110                 return name;
111             }
112         }
113
114         public override string Description
115         {
116             get
117             {
118                 return string.Format("{0} description", name);
119             }
120         }
121
122         public override bool IsReadOnly
123         {
124             get { return false; }
125         }
126
127         public override string Name
128         {
129             get
130             {
131                 return "fs2_" + name;
132             }
133         }
134
135         public override Type ComponentType
136         {
137             get { throw new NotImplementedException(); }
138         }
139
140         public override object GetValue(object component)
141         {
142             //do something
143             return "";
144         }
145
146         public override Type PropertyType
147         {
148             get { return typeof(string); }
149         }
150
151         public override void ResetValue(object component)
152         {
153             throw new NotImplementedException();
154         }
155
156         public override void SetValue(object component, object value)
157         {
158             //do something
159         }
160
161         public override bool ShouldSerializeValue(object component)
162         {
163             return false;
164         }
165     }
166 }

  新建Windows工程,添加该文件,在Form中拖入一个PropertyGrid控件和MyControl控件,在Form的构造函数中添加如下代码:

  this.propertyGrid1.PropertyTabs.AddTabType(typeof(EventsTab));

  this.propertyGrid1.SelectedObject = this.myControl1;

  运行程序,查看效果。

  这里只是实现了非常简单的功能,仅仅显示了控件的事件,而不能编辑,如果要达到VS那种效果,需要完善EventWrapper类。

  还是那句话,个人浅见,错漏不正之处,敬请指出,万分感谢!

时间: 2024-08-05 18:10:37

PropertyGrid—添加EventTab的相关文章

PropertyGrid—添加属性Tab

零.引言 PropertyGrid用来显示和编辑对象的属性,前面已经简单介绍了如何使用该控件和提供不同的属性编辑方法.前面主要讲如何使用该控件,但有时,该控件无法满足我们的需求,就需要对其进行扩展.本文主要介绍如何在PropertyGrid中添加属性选项卡(PropertyTab).VS自带的属性框有属性和事件两个属性卡,下面简单说明如何添加自己的选项卡. 一.PropertyGrid的组成 在添加选项卡之前,先来看一看PropertyGrid的组成,分析其组成对后面设计十分有用.微软将Prop

PropertyGrid 重难点总结 转

PropertyGrid的界面组成与不同部分的名称如下图所示. 本博文不算是自己写作的,只是将PropertyGrid中的几项十分有用的功能的应用方面的文字进行一下总结,希望以后大家对PropertyGrid使用时,不会感到缺少必要的技术资料.PS: 以后凡是遇到相关的技术难题,希望大家多多查看MSDN,这样的资料通常比较系统,而且十分权威,网上的很多东西的操作虽然更有针对性,但是也比较零碎,使用起来不能从全局入手. .NET Framework 类库,MSDN 中文名称的显示 [Categor

Mfc PropertyGrid Control 添加之后点击无反应的问题

设置Mfc PropertyGrid Control的属性[Notify]为True 原文地址:https://www.cnblogs.com/Rmumu/p/12275164.html

System.Windows.Forms.PropertyGrid的使用

PropertyGrid 控件简介 .NET 框架 PropertyGrid 控件是 Visual Studio .NET 属性浏览器的核心.PropertyGrid 控件显示对象或类型的属性,并主要通过使用反射来检索项目的属性.当我们创建了一个类编译之后就生成了类的Metadata,元数据.PropertyGrid 就是使用反射来展示和修改类的公共属性的,就是public标识的属性.但凡成熟的软件都是使用配置来满足不同场景或者客户的需求,就是使用参数开关的形式.PropertyGrid 代表了

通过反射更改PropertyGrid的只读以及可见特性

在开发Winform程序中,PropertyGrid是一个常用的控件,在使用PropertyGrid的过程中,只需要将对应的对象实例赋给PropertyGrid的SelectedObject属性即可.当然,需要在对应的对象定义中添加相应的属性. 1 class Human 2 { 3 private int _age; 4 private string _name; 5 private Gender _gender; 6 7 [DisplayName("姓名"), 8 Browsabl

NET 框架 PropertyGrid 控件

NET框架PropertyGrid控件是 Visual Studio .NET 属性浏览器的核心.PropertyGrid控件显示对象或类型的属性,并主要通过使用反射来检索项目的属性 首先创建 PropertyGrid 控件要使用 Visual Studio .NET 创建 PropertyGrid 控件,需要将该控件添加到工具箱中,因为默认情况下并不包含该控件.在 Tools(工具)菜单中,选择 Customize Toolbox(自定义工具箱).在对话框中选择 Framework Compo

WinForm窗体PropertyGrid控件的使用

使用过 Microsoft Visual Basic 或 Microsoft Visual Studio .NET的朋友,一定使用过属性浏览器来浏览.查看或编辑一个或多个对象的属性..NET 框架 PropertyGrid 控件是 Visual Studio .NET 属性浏览器的核心.PropertyGrid 控件显示对象或类型的属性,并主要通过使用反射(在运行时提供类型信息的技术)来检索项目的属性.PropertyGrid控件包含以下部分:一般属性.可展开属性.属性类别.属性说明和属性编辑器

C# PropertyGrid控件应用心得

何处使用 PropertyGrid 控件 在应用程序中的很多地方,您都可以使用户与 PropertyGrid 进行交互,从而获得更丰富的编辑体验.例如,某个应用程序包含多个用户可以设置的“设置”或选项,其中一些可能十分复杂.您可以使用单选按钮.组合框或文本框来表示这些选项.但本文将逐步介绍如何使用 PropertyGrid 控件创建选项窗口来设置应用程序选项.上面所创建的 OptionsDialog 窗体即是选项窗口的开始.现在,我们创建一个名为 AppSettings 的类,其中包含映射到应用

PropertyGrid—默认属性,默认事件,属性默认值

零.引言 PropertyGrid显示一个对象的属性和事件时,可以设置其默认属性和事件,也就是当你选中对象时,propertyGrid中焦点在哪一个属性或事件上.为对象的属性提供默认值,使PropertyGrid显示属性时,更加友好. 一.默认属性和默认事件 PropertyGrid能识别默认属性和事件,例如在设计时,双击Form框,就会跳到Form的Load事件中,这是因为Form的默认事件是Load.当你选中属性框中的某一项后,该项会着色(蓝色)选中,在属性和事件选项卡之间切换,就会发现,选