零.引言

  前面一篇文章介绍了如何在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:

  

     class EventWrapper : PropertyDescriptor
{
string name; //名字
public EventWrapper(string name)
: base(name, null)
{
this.name = name;
} public override bool CanResetValue(object component)
{
return true;
} public override string DisplayName
{
get
{
return name;
}
} public override string Description
{
get
{
return string.Format("{0} description", name);
}
} public override bool IsReadOnly
{
get { return false; }
} public override string Name
{
get
{
return "fs2_" + name;
}
} public override Type ComponentType
{
get { throw new NotImplementedException(); }
} public override object GetValue(object component)
{
//do something
return "";
} public override Type PropertyType
{
get { return typeof(string); }
} public override void ResetValue(object component)
{
throw new NotImplementedException();
} public override void SetValue(object component, object value)
{
//do something
} public override bool ShouldSerializeValue(object component)
{
return false;
}
}

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

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

  

 public class EventsTab : System.Windows.Forms.Design.PropertyTab
{
[BrowsableAttribute(true)]
// This string contains a Base-64 encoded and serialized example property tab image.
private string img = "AAEAAAD/////AQAAAAAAAAAMAgAAAFRTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0xLjAuMzMwMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA9gAAAAJCTfYAAAAAAAAANgAAACgAAAAIAAAACAAAAAEAGAAAAAAAAAAAAMQOAADEDgAAAAAAAAAAAAD///////////////////////////////////9ZgABZgADzPz/zPz/zPz9AgP//////////gAD/gAD/AAD/AAD/AACKyub///////+AAACAAAAAAP8AAP8AAP9AgP////////9ZgABZgABz13hz13hz13hAgP//////////gAD/gACA/wCA/wCA/wAA//////////+AAACAAAAAAP8AAP8AAP9AgP////////////////////////////////////8L"; public override System.ComponentModel.PropertyDescriptorCollection GetProperties(object component, Attribute[] attributes)
{
//Return list of known events
EventDescriptorCollection events_info;
if (attributes == null)
events_info = TypeDescriptor.GetEvents(component);
else
events_info = TypeDescriptor.GetEvents(component, attributes);
//封装事件
var events = new PropertyDescriptor[events_info.Count];
for (int i = ; i < events_info.Count; i++)
events[i] = new EventWrapper(events_info[i].Name); return new PropertyDescriptorCollection(events);
} public override string TabName
{
get { return "Events"; }
} public override System.Drawing.Bitmap Bitmap
{
get
{
Bitmap bmp = new Bitmap(DeserializeFromBase64Text(img)); return bmp;
}
} private Image DeserializeFromBase64Text(string text)
{
Image img = null;
byte[] memBytes = Convert.FromBase64String(text);
IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream(memBytes);
img = (Image)formatter.Deserialize(stream);
stream.Close();
return img;
}
}

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

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

  

  可见,事件都列出来了。

三.完整代码

  下面是完整代码:

  

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary; namespace TestAddTab
{
//控件类
//[PropertyTabAttribute(typeof(MyPropertyTab), PropertyTabScope.Component)]
public class MyControl : System.Windows.Forms.UserControl
{
private double _angle = ; public MyControl()
{
} [BrowsableAttribute(true)]
[Category("角度")]
public double Angle
{
get
{ return _angle; }
set
{ _angle = value; }
} protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
e.Graphics.DrawString("The Angle is " + _angle, this.Font, Brushes.Red, , );
}
} public class EventsTab : System.Windows.Forms.Design.PropertyTab
{
[BrowsableAttribute(true)]
// This string contains a Base-64 encoded and serialized example property tab image.
private string img = "AAEAAAD/////AQAAAAAAAAAMAgAAAFRTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0xLjAuMzMwMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA9gAAAAJCTfYAAAAAAAAANgAAACgAAAAIAAAACAAAAAEAGAAAAAAAAAAAAMQOAADEDgAAAAAAAAAAAAD///////////////////////////////////9ZgABZgADzPz/zPz/zPz9AgP//////////gAD/gAD/AAD/AAD/AACKyub///////+AAACAAAAAAP8AAP8AAP9AgP////////9ZgABZgABz13hz13hz13hAgP//////////gAD/gACA/wCA/wCA/wAA//////////+AAACAAAAAAP8AAP8AAP9AgP////////////////////////////////////8L"; public override System.ComponentModel.PropertyDescriptorCollection GetProperties(object component, Attribute[] attributes)
{
//Return list of known events
EventDescriptorCollection events_info;
if (attributes == null)
events_info = TypeDescriptor.GetEvents(component);
else
events_info = TypeDescriptor.GetEvents(component, attributes); var events = new PropertyDescriptor[events_info.Count];
for (int i = ; i < events_info.Count; i++)
events[i] = new EventWrapper(events_info[i].Name); return new PropertyDescriptorCollection(events);
} public override string TabName
{
get { return "Events"; }
} public override System.Drawing.Bitmap Bitmap
{
get
{
Bitmap bmp = new Bitmap(DeserializeFromBase64Text(img));
return bmp;
}
} private Image DeserializeFromBase64Text(string text)
{
Image img = null;
byte[] memBytes = Convert.FromBase64String(text);
IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream(memBytes);
img = (Image)formatter.Deserialize(stream);
stream.Close();
return img;
}
} class EventWrapper : PropertyDescriptor
{
string name;
public EventWrapper(string name)
: base(name, null)
{
this.name = name;
} public override bool CanResetValue(object component)
{
return true;
} public override string DisplayName
{
get
{
return name;
}
} public override string Description
{
get
{
return string.Format("{0} description", name);
}
} public override bool IsReadOnly
{
get { return false; }
} public override string Name
{
get
{
return "fs2_" + name;
}
} public override Type ComponentType
{
get { throw new NotImplementedException(); }
} public override object GetValue(object component)
{
//do something
return "";
} public override Type PropertyType
{
get { return typeof(string); }
} public override void ResetValue(object component)
{
throw new NotImplementedException();
} public override void SetValue(object component, object value)
{
//do something
} public override bool ShouldSerializeValue(object component)
{
return false;
}
}
}

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

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

  this.propertyGrid1.SelectedObject = this.myControl1;

  运行程序,查看效果。

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

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

PropertyGrid—添加EventTab的更多相关文章

  1. PropertyGrid—添加属性Tab

    零.引言 PropertyGrid用来显示和编辑对象的属性,前面已经简单介绍了如何使用该控件和提供不同的属性编辑方法.前面主要讲如何使用该控件,但有时,该控件无法满足我们的需求,就需要对其进行扩展.本 ...

  2. PropertyGrid 重难点总结 转

    PropertyGrid的界面组成与不同部分的名称如下图所示. 本博文不算是自己写作的,只是将PropertyGrid中的几项十分有用的功能的应用方面的文字进行一下总结,希望以后大家对Property ...

  3. PropertyGrid 重难点总结

    PropertyGrid的界面组成与不同部分的名称如下图所示. 本博文不算是自己写作的,只是将PropertyGrid中的几项十分有用的功能的应用方面的文字进行一下总结,希望以后大家对Property ...

  4. 关于PropertyGrid控件的排序问题

    前些天,由于在项目中需要用到PropertyGrid这个控件,展现其所在控件的某些属性,由于有些控件的属性较多,不易浏览,而且PropertyGrid的排序默认的按照字母的顺序排列的,这样导致在在某些 ...

  5. C# extended toolkit propertygrid 隐藏部分属性

    该方法是通过更改ShowDetail的状态来实现的隐藏属性 首先在引用里右键 管理NuGet程序包 查找extended wpf toolkit 并安装 然后在MainWindow.xaml添加引用 ...

  6. C#动态添加属性

    class DynamicInputParams: DynamicObject { Dictionary<string, object> property = new Dictionary ...

  7. WinForm窗体PropertyGrid控件的使用

    使用过 Microsoft Visual Basic 或 Microsoft Visual Studio .NET的朋友,一定使用过属性浏览器来浏览.查看或编辑一个或多个对象的属性..NET 框架 P ...

  8. C# PropertyGrid控件应用心得

    何处使用 PropertyGrid 控件 在应用程序中的很多地方,您都可以使用户与 PropertyGrid 进行交互,从而获得更丰富的编辑体验.例如,某个应用程序包含多个用户可以设置的“设置”或选项 ...

  9. 自定义控件如何给特殊类型的属性添加默认值 z

    定义控件如何给特殊类型的属性添加默认值了,附自定义GroupBox一枚 标题有点那啥,但确实能表达我掌握此法后的心情. 写自定义控件时往往会有一个需求,就是给属性指定一个默认值(就是可以在VS中右键该 ...

随机推荐

  1. JAVA HashMap与HashTable 区别

    HashTable和HashMap区别 第一,继承不同. public class Hashtable extends Dictionary implements Mappublic class Ha ...

  2. NDK下 将Platinum SDK 编译成so库 (android - upnp)

    Platinum UPnP SDK 是一个跨平台的C++库,利用该库,可以很容易就构建出DLNA/UPnP控制点(DLNA/UPnP Control Point)和DLNA/UPnP设备(DLNA/U ...

  3. css阴影--box-shadow的用法

    原文:http://blog.csdn.net/freshlover/article/details/7610269 text-shadow是给文本添加阴影效果,box-shadow是给元素块添加周边 ...

  4. for循环删除集合陷阱

    首先看下面的代码: import java.util.LinkedList;import java.util.List; public class DeleteCollection {         ...

  5. CMD下修改IP地址

    @echo off netsh interface ip set address name="本地连接" static 192.168.1.55 255.255.255.0 192 ...

  6. windows笔记

    三星(SAMSUNG)905S3G-K07 安装Windows 7 过程分享 http://www.cnblogs.com/scue/p/4100743.html 打开方式没有excel http:/ ...

  7. 班上有学生若干名,已知每名学生的成绩(整数),求班上所有学生的平均成绩,保留到小数点后两位。同时输出该平均成绩整数部分四舍五入后的数值。 第一行有一个整数n(1<= n <= 100),表示学生的人数。其后n行每行有1个整数,表示每个学生的成绩,取值在int范围内。

    #include<iostream> #include<iomanip> using namespace std ; int main() { int n; while(cin ...

  8. windows本地搭建grunt前端项目构建环境

    初学,目前对grunt的理解和需求仅在于简单的文件合并.压缩.语法检查,其强大功能还有待研究. 安装前环境准备 (1)grunt依赖nodejs运行环境,所以要玩grunt得先把nodejs安装好,n ...

  9. oracle 集合定义

    集合:是具有相同定义的元素的聚合.Oracle有两种类型的集合: 可变长数组(VARRAY):可以有任意数量的元素,但必须预先定义限制值. 嵌套表:视为表中之表,可以有任意数量的元素,不需要预先定义限 ...

  10. ListView的小知识

    1.设置项目分割功能 android:divider="@android:color/blue" android:dividerHeight="10dp" &l ...