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:
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的更多相关文章
- PropertyGrid—添加属性Tab
零.引言 PropertyGrid用来显示和编辑对象的属性,前面已经简单介绍了如何使用该控件和提供不同的属性编辑方法.前面主要讲如何使用该控件,但有时,该控件无法满足我们的需求,就需要对其进行扩展.本 ...
- PropertyGrid 重难点总结 转
PropertyGrid的界面组成与不同部分的名称如下图所示. 本博文不算是自己写作的,只是将PropertyGrid中的几项十分有用的功能的应用方面的文字进行一下总结,希望以后大家对Property ...
- PropertyGrid 重难点总结
PropertyGrid的界面组成与不同部分的名称如下图所示. 本博文不算是自己写作的,只是将PropertyGrid中的几项十分有用的功能的应用方面的文字进行一下总结,希望以后大家对Property ...
- 关于PropertyGrid控件的排序问题
前些天,由于在项目中需要用到PropertyGrid这个控件,展现其所在控件的某些属性,由于有些控件的属性较多,不易浏览,而且PropertyGrid的排序默认的按照字母的顺序排列的,这样导致在在某些 ...
- C# extended toolkit propertygrid 隐藏部分属性
该方法是通过更改ShowDetail的状态来实现的隐藏属性 首先在引用里右键 管理NuGet程序包 查找extended wpf toolkit 并安装 然后在MainWindow.xaml添加引用 ...
- C#动态添加属性
class DynamicInputParams: DynamicObject { Dictionary<string, object> property = new Dictionary ...
- WinForm窗体PropertyGrid控件的使用
使用过 Microsoft Visual Basic 或 Microsoft Visual Studio .NET的朋友,一定使用过属性浏览器来浏览.查看或编辑一个或多个对象的属性..NET 框架 P ...
- C# PropertyGrid控件应用心得
何处使用 PropertyGrid 控件 在应用程序中的很多地方,您都可以使用户与 PropertyGrid 进行交互,从而获得更丰富的编辑体验.例如,某个应用程序包含多个用户可以设置的“设置”或选项 ...
- 自定义控件如何给特殊类型的属性添加默认值 z
定义控件如何给特殊类型的属性添加默认值了,附自定义GroupBox一枚 标题有点那啥,但确实能表达我掌握此法后的心情. 写自定义控件时往往会有一个需求,就是给属性指定一个默认值(就是可以在VS中右键该 ...
随机推荐
- ffmpeg API录制rtsp视频流
原文出自http://blog.csdn.net/zxwangyun/article/details/8190638#reply 作者 Sloan 这里在录制时,并没有进行转码,只是相当于把rts ...
- WPFS数据绑定(要是后台类对象的属性值发生改变,通知在“client界面与之绑定的控件值”也发生改变须要实现INotitypropertyChanged接口)
WPFS数据绑定(要是后台类对象的属性值发生改变,通知在"client界面与之绑定的控件值"也发生改变须要实现INotitypropertyChanged接口) MainWindo ...
- Android 之 Gallery
1 在 xml 布局中添加 Gallery activity_main.xml <LinearLayout xmlns:android="http://schemas.andro ...
- 下拉菜单中的Option对象
1.创建Option对象 1.1 var optionEle1 = document.createElement('option'); 1.2 var optionEle2 = new Option( ...
- [原创] Assistant editor 取消拖拽 binding 的 UI 元素
1. press up-right button "show the utilities" 2. press "show the Connections inspecto ...
- Core Bluetooth 概述 【官方文档翻译】
Core Bluetooth 框架在Mac和iOS平台,为配备了低功耗蓝牙无线技术的设备提供了进行通信所需要的类.例如,您的应用程序可以发现,探索,和低功耗的外围设备进行交互,如心率监视器.数字温控器 ...
- SqlHelper 简单版
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...
- Java三大特征之多态(三)
面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...
- css3渐变详解
今天总结渐变的问题,渐变分为线性渐变.径向渐变.呼呼,废话少说, 线性渐变:background:linear-gradient(设置渐变形式,第一个颜色起点,中间颜色点 中间颜色的位置,结束点颜色) ...
- chapter 1 Number/Adventurous Person
part1: 1- Which would be easier to remember a munber or a name? Well, I am better at remembering num ...