之前已经对委托和事件有一些些了解,但由于对概念理解的不完全以及不知道如何使用委托和事件,所以一直以来对这二个词总感觉朦朦胧胧的。这二天颇费了点时间,一边回顾一边查阅,一边理解一边动手做实验,因此基本掌握了其概念和运用方法。
概念不想再写了,网上很多 下面是我做的实验+注释
更详尽了解委托和事件的文章请点击:http://www.cnblogs.com/jimmyzhang/archive/2007/09/23/903360.html (讲解得非常棒,而且最后还结合了OBsever设计模式和.Net Framework的编码规范进行说明)
实验内容:由文件2 (窗体文件)中单击登陆按钮来调用文件1(类代码文件)中的方法:Login()。文件1中定义了LoginEven事件 ,文件1和文件2都向LoginEven事件注册了方式(添加委托),并在文件1类被创建时(构建函数中)执行此事件。
文件1:UserEvent.CS (类代码文件)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace @delegate
{
//public delegate void LoginEvenHandler(string message); //委托可以定义在Class之外(出于面向对象的封装性,不建议这么做,因为你不知道这个委托类型是与哪个类关联的,没有层次感),这样我们可以直接通过namespace.delegatename(@delegate.LoginEvenHandler)来使用它
class UserEvent
{
/// <summary>
/// 用户登陆的委托类型
/// </summary>
/// <param name="message"></param>
public delegate void LoginEvenHandler(string message); //定义一个委托。 公有变量以让外部可见。委托是一种类型。类型是属于类的而不属于对象,所以外部调用此类型时应该使用[类名.委托名] 而不是[对象名.委托名]
/// <summary>
/// 用户的登陆事件
/// </summary>
public event LoginEvenHandler LoginEven; //根据委托类型名定义一个事件。公有变量以让外部可见。事件是类的成员,就像属性是类的成员一样。事件是一个委托链 里面可以放N多方法签名相同的委托或方法。因此如果想在实例化对象前使用它就必须声明为静态成员。
string timeNow = DateTime.Now.ToString(); //定义一个时间字符串。给事件用
public UserEvent()
{
//每次构建类时 将重置事件
LoginEven = MessageShow; //C#2.0以后的写法 无需要new 就可以直接将方法名放进事件里
//LoginEven = new LoginEvenHandler(MessageShow); //C#的早期写法,new出来的方法(将方法封装成委托)再放进事件里
}
private void MessageShow(string t)
{//LoginEven事件需要执行的方法中的一个
string mess = "UserEvent类被创建了。事件中目前只有此一个方法,它是UserEvent类本身的方法,当前创建的时间是:" + t;
MessageBox.Show(mess);
}
public void Login()
{
//执行此事件!特别注意:只有在定义事件的类中才可以执行事件!!!除此之外,只能用+=、-+向事件注册或注销方法,也就是在编译器中会看到的错误:事件只能出现在+=或-=的左边的说法
//此处用到timeNow。事件里的所有委托将以timeNow作为参数一一调用(事件向委托传递调用参数)
LoginEven(timeNow); //执行事件时事件里的委托必须不能为空,也就是至少有一个委托。这里我在构建类的函数中重置成一个委托,用户可以在构建后向事件内添加新委托。
}
}
}
文件2:F_Login.CS(WINDOWS窗体代码文件)
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 @delegate
{
public partial class F_Login : Form
{
public F_Login()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
UserEvent userEvent = new UserEvent(); //由于类构建函数已重置了事件(为一个委托),所以每次创建对象时,对象事件里的委托只有一个。
userEvent.LoginEven += MessboxShow; //向对象的事件添加一个委托,此时就是二个委托。除非是在定义事件的类中,否则必须使用+= 或-+ 而不能使用=,使用-=时如果不存在被减去的委托则会忽略此语句。
//userEvent.LoginEven += new UserEvent.LoginEvenHandler(MessboxShow); //1、这是C#2.0以前的写法,它是将方法用new封装成匿名委托后再放进事件里。
//从这里可以看到委托其实就是将方法(MessboxShow)作为参数进行传递。
//UserEvent.LoginEvenHandler m = new UserEvent.LoginEvenHandler(MessboxShow); //这里是将上面的匿名委托变成有名称的委托(m)的写法,它由上面一行变成了二行代码。
//userEvent.LoginEven += m;
userEvent.Login(); //调用userEvent的Login()方法,在Login()中会执行LoginEven事件
}
private void MessboxShow(string t)
{//LoginEven事件需要执行的方法中的一个
string messbox = "这里在UserLogin类代码以外执行的方法,从委托得到此对象创建的时间是:" + t;
MessageBox.Show(messbox);
}
}
}