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:

    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;
            }
        }
    View Code

      继承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 = 0; 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 = 90;
    
            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, 0, 0);
            }
        }
    
        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 = 0; 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;
            }
        }
    }
    View Code

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

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

      this.propertyGrid1.SelectedObject = this.myControl1;

      运行程序,查看效果。

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

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

     

     

    (原文)

  • 相关阅读:
    带妹入坑,她该怎样提高自己的编程能力?
    性能测试--cpu使用率过高怎么办
    loadrunner Controller 删除available scripts中无用脚本
    loadrunner 立即执行+定时执行设置
    loadrunner11 :脚本日志打印设置及举例说明
    loadrunner录制chrome脚本:页面无响应
    Error -27492: "HttpSendRequest" failed, Windows error code=12152 (invalid server response) and retry。。。
    loadrunner11错误:Error -27776: Server "wsg.cmszmail.ad" shut connection during attempt to negotiate SSL session [MsgId: MERR-27776]解决办法
    loadrunner11 错误:Error -26377: No match found for the requested parameter XXXX. web_custom_request(XXX) highest severity level was "ERROR",....... [MsgId: MMSG-26387]
    loadrunner11 执行bat批处理文件时获取bat文件所在路径 正确方式与采坑说明
  • 原文地址:https://www.cnblogs.com/code1992/p/10197123.html
Copyright © 2011-2022 走看看