zoukankan      html  css  js  c++  java
  • 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     }
    View Code

      继承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 }
    View Code

      唯一的不同是在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 }
    View Code

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

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

      this.propertyGrid1.SelectedObject = this.myControl1;

      运行程序,查看效果。

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

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

  • 相关阅读:
    finalShell 文件上传拖拽失败
    centos6.x 启动docker报错
    笔记本查看当前登录用户
    保存文件到D盘时显示“你没有权限在此文件夹中保存文件,请联系管理员“其他文件夹正常?
    关于MongoDB配置文件的一个小细节
    ubuntu: mongoDB安装,无需下载
    Java 连接虚拟机中MongoDB 所需依赖
    信息知识竞赛刷题助手
    python超多常用知识记录
    python字典键或值去重
  • 原文地址:https://www.cnblogs.com/yongyu/p/4232506.html
Copyright © 2011-2022 走看看