之前一直没有搞懂委托和事件的相关含义,而且网上的教程又比较抽象臃肿,我实在是一个脑袋比较笨又很懒的人,所以就这么不了了之到现在。最近碰到很多需要委托事件的实际需要,比如自定义用户控件。刚刚求同事指导一番,发现了一个比较好用的方法来实现需求,具体过程如下:
一.需求
现在我创建了一个自定义控件 TestUserControl,单击这个用户控件的时候,会返回这个用户控件对应的属性类 TestPropertyClass,在父窗体TestForm(即调用窗体)中拖拉了此用户控件,窗体本身有一个显示属性用的VS自带的控件PropertyGrid(如下图),窗体运行的时候,PropertyGrid控件会调用TestPropertyClass从而显示出TestUserControl对应的属性值。
二.实现
1.TestPropertyClass代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; namespace test { public class TestPropertyClass { private string _name = "Google"; [DisplayName("网站名")] public string Name { get { return _name; } set { _name = value; } } private string _Domain = "www.google.com"; [DisplayName("域名")] public string Domain { get { return _Domain; } set { _Domain = value; } } [DisplayName("搜索关键字")] public string SearchKey { get; set; } } }
2.TestUserControl中代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; namespace test { public partial class TestUserControl : UserControl { public TestUserControl() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { if (ClickEvent != null) { ClickEvent(new TestPropertyClass()); } } public event Action<TestPropertyClass> ClickEvent; } }
3.TestForm的代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace test { public partial class TestForm : Form { public TestForm() { InitializeComponent(); } private void testUserControl1_ClickEvent(TestPropertyClass obj) { propertyGrid1.SelectedObject = obj; } } }
其实,最主要的代码是在TestUserControl中,
public event Action<TestPropertyClass> ClickEvent; 这句话是定义了一个泛型委托事件,相当于下面两句代码的组合:
public delegate void delegateEventHandle(TestPropertyClass obj);
public event delegateEventHandle ClickEvent;
下面的方法:
private void button1_Click(object sender, EventArgs e)
{
if (ClickEvent != null) //判断事件是否为空
{
ClickEvent(new TestPropertyClass());//不为空就执行事件并传入一个实例化后的类TestPropertyClass作为参数
}
}
在前台的TestForm里面,我们直接右键TestUserControl1查看起事件列表会发现多一个事件 ClickEvent即我们上面自定义的事件对象,然后我们直接在ClickEvent事件里面写上相应的代码即可,当然,我这里写的有些乱,只是介绍下大概的流程。你也可以不用propertyGrid控件直接画一些页面比如简单的传个用户姓名进行尝试。
private void testUserControl1_ClickEvent(TestPropertyClass obj)
{
propertyGrid1.SelectedObject = obj;//实现propertyGrid1属性(不懂可以网上搜索propertyGrid)
}