零.引言

  前面一篇文章介绍了如何在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. [Spring boot] web应用返回jsp页面

    同事创建了一个spring boot项目,上传到svn.需要我来写个页面.下载下来后,始终无法实现在Controller方法中配置直接返回jsp页面. 郁闷了一下午,终于搞定了问题.在此记录一下. 目 ...

  2. Linux使用技巧9--用dpkg管理你的软件

    dpkg(package manager for Debian): debian体系中的包管理工具. Commands: -i|--install <.deb file name> ... ...

  3. NET基础课--NET中程序集0-1

    程序集 1.表现形式:.dll  和. exe . 2.程序集组成:PE头,CLR头,清单,元数据,CIL代码,资源文件.实际上这些内容包含在一个叫做Module的逻辑结构中. 单模块程序集:程序集就 ...

  4. 在linq查询环境下通过sql语句来访问数据库

    接上一篇随笔 这里主要介绍在linq环境下,如果实现用sql来访问数据库,同时也介绍在EF框架中如何添加新的方法来访问数据库. 1.首先,在数据访问层(EF.DAO,EF.IDAO)中添加具体的函数来 ...

  5. ORACLE OCP认证

    基本情况介绍 Oracle产品非常多,这里说的是Oracle数据库认证体系. Oracle数据库认证体系包括3层,分别是OCA(助理),OCP(专家),OCM(大师) 一般情况下,需一级一级认证,也就 ...

  6. Oracle如何只显示重复数据,或不显示重复数据

    思路:  一.对所有字段进行分组并计数  二.计数大于1的就显示 select * from 表名 group by 字段1,字段2 having count(*)>1 (显示重复)

  7. Ubuntu修改计算机名称造成无法解析主机问题解决方法

    在通过修改/etc/hostname文件方法修改计算机名称后导致有时候出现无法解析主机的问题. 解决方法: 找到/etc/hosts文件,打开找到如下一行 127.0.1.1       旧主机名 将 ...

  8. bluestacks安装安卓引擎时出现2502 2503错误的解决办法

    2503代表工作站无法启动.2502代表下面的程序调用不支持的MS-DOS函数. 以管理员身份运行命令提示符在经典桌面使用快捷键Win+X,出现一个菜单,选择“命令提示符(管理员) ”即可以以管理员身 ...

  9. $ cd `dirname $0` 和PWD%/* shell变量的一些特殊用法

    在命令行状态下单纯执行 $ cd `dirname $0` 是毫无意义的.因为他返回当前路径的".". $0:当前Shell程序的文件名dirname $0,获取当前Shell程序 ...

  10. 依赖注入 | Dependency Injection

    原文链接: Angular Dependency Injection翻译人员: 铁锚翻译时间: 2014年02月10日说明: 译者认为,本文中所有名词性的"依赖" 都可以理解为 & ...