1、 事件简单理解
可以理解为对象对外部情况作出相应的响应,如:用户在UI中单击自定义控件时,该控件会触发click事件。
2、 事件的工作方式
(1)首先,必须在类中声明事件并确定将要使用的委托和参数
(2)其次必须定义在触发事件时要调用的委托
(3)最后,必须设计事件参数类,该参数类的实例会将信息传递给调用的方法
理解以上三点可以用这个例子:小孩子玩气球(气球类),气球有最大容积当充气超出容积会爆炸(爆炸事件),当小孩听到爆炸声吓哭了。
class Program
{
//第一步:类外面定义委托,使用类发生事件时外部可以根据本委托处理事件
public delegate void 爆炸EventHandler();//事件处理程序
public class Balloon
{
private readonly int _Max容积;
private int _当前容积;
public int 最大容积
{
get { return this._Max容积; }
}
//构造函数
public Balloon(int 最大容积)
{
this._Max容积 = 最大容积;
}
//第二步:在类的内部,定义该类具有那个事件
//调用事件时,必须判断事件是否为空
public event 爆炸EventHandler 爆炸event;//事件关键字+委托名+事件名
//充气方法
public void 充气(int 充气体积)
{
this._当前容积 += 充气体积;
if (this._当前容积>this.最大容积)
{
//触发爆炸事件,并通知别人气球爆炸了
//判断是不是有注册过事件的处理程序
//第三步:激发事件
if (this.爆炸event!=null)
{
this.爆炸event();
}
}
}
}
public class 小孩
{
private Balloon _ball;
public 小孩(Balloon ball)
{
this._ball = ball;
//第四步:注册事件
//注册事件的处理程序,小孩会处理打气事件
//注册:事件源名+=new 时间委托类型(事件处理方法);
this._ball.爆炸event += new 爆炸EventHandler(this.听到气球爆炸);
this._ball.爆炸event += new 爆炸EventHandler(_ball_爆炸event);
}
//第五步:实现事件发生时要调用的方法(通俗的说事件触发时候该做什么)
void _ball_爆炸event()
{
Console.WriteLine("小孩子吓哭了!");
}
public void 打气(int m)
{
this._ball.充气(m);
}
public void 听到气球爆炸()
{
Console.WriteLine("处理者:气球爆炸了");
}
}
static void Main(string[] args)
{
Balloon ball = new Balloon(20);
小孩 boy1 = new 小孩(ball);
boy1.打气(5);
boy1.打气(5);
boy1.打气(5);
boy1.打气(5);
boy1.打气(5);
}
}
通过以上可总结出:使用事件的一般步骤(以上例为例子):
第一步:定义处理事件的委托,也即事件的处理程序;
如:public delegate void 爆炸EventHandler();
第二步:在类的内部定义事件,指定事件处理的委托类型,也即定义事件
如: public event 爆炸EventHandler 爆炸event;//事件关键字+委托名+事件名
第三步:在类内部在适当的时候触发事件,通俗的说是调用事件,类似于调用委托;
如:if (this._当前容积>this.最大容积)
{
if (this.爆炸event!=null)
{
this.爆炸event();
}
}
第四步:再类的外部(也可以在内部)注册类的事件处理程序。
//注册:事件源名+=new 时间委托类型(事件处理方法);
this._ball.爆炸event += new 爆炸EventHandler(this.听到气球爆炸);
this._ball.爆炸event += new 爆炸EventHandler(_ball_爆炸event);
第五步:实现事件触发时要处理的方法,如this.听到气球爆炸()和_ball_爆炸event();
3、 简单的事件原理我们应该通过上面的例子明白了,下面我们深入了解下:(简单介绍小时间参数类EventArgs)
加入我们还以上例子为标准,我们提出这样一个需求:小孩子吓哭的同时想知道爆炸的时间?该如何解决?
其实很简单,只需在注册事件委托时候加入一个需要的参数即可,改动的地方如下:
public delegate void 爆炸EventHandler(DateTime dt);
void _ball_爆炸event(DateTime dt)
{
Console.WriteLine("小孩子吓哭了!");
}
public void 打气(int m)
{
this._ball.充气(m);
}
public void 听到气球爆炸(DateTime dt)
{
Console.WriteLine("处理者:气球爆炸了,爆炸时间是:{0}",dt);
}
显然这个问题解决了,那么加入又增加了需求,不仅要知道气球爆炸的时间还想知道,爆炸的地点等,那么我们还需继续改动,若以后有更多的参数,我们就得不断地改动很多地方,岂不是很累?那么该怎么办呢?很显然,利用面向对象的思想,把委托的参数抽象成一个类,即可解决,也即形成了所谓的事件参数类。
//事件参数类
public class BalloonEventArgs
{
private DateTime dt;
public DateTime Dt
{
get { return dt; }
set { dt = value; }
}
private string address;
public string Address
{
get { return address; }
set { address = value; }
}
public BalloonEventArgs(DateTime dt1, string add)
{
this.Dt = dt1;
this.address = add;
}
}
这样以后如果再有什么参数要加入,直接修改类里面的字段即可,不必修改每个委托参数和方法。完整代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
public delegate void 爆炸EventHandler(BalloonEventArgs e);
public class Balloon
{
private readonly int _Max容积;
private int _当前容积;
public int 最大容积
{
get { return this._Max容积; }
}
//构造函数
public Balloon(int 最大容积)
{
this._Max容积 = 最大容积;
}
public event 爆炸EventHandler 爆炸event;
public void 充气(int 充气体积)
{
this._当前容积 += 充气体积;
if (this._当前容积 > this.最大容积)
{
if (this.爆炸event != null)
{
BalloonEventArgs arg = new BalloonEventArgs(DateTime.Now, "南阳理工学院");
this.爆炸event(arg);
}
}
}
}
public class 小孩
{
private Balloon _ball;
public 小孩(Balloon ball)
{
this._ball = ball;
this._ball.爆炸event += new 爆炸EventHandler(this.听到气球爆炸);
this._ball.爆炸event += new 爆炸EventHandler(_ball_爆炸event);
}
void _ball_爆炸event(BalloonEventArgs e)
{
Console.WriteLine("小孩子吓哭了!");
}
public void 打气(int m)
{
this._ball.充气(m);
}
public void 听到气球爆炸(BalloonEventArgs e)
{
Console.WriteLine("处理者:气球爆炸了,爆炸时间是:{0},爆炸地点是:{1}",e.Dt,e.Address);
}
}
public class BalloonEventArgs
{
private DateTime dt;
public DateTime Dt
{
get { return dt; }
set { dt = value; }
}
private string address;
public string Address
{
get { return address; }
set { address = value; }
}
public BalloonEventArgs(DateTime dt1, string add)
{
this.Dt = dt1;
this.address = add;
}
}
static void Main(string[] args)
{
Balloon ball = new Balloon(20);
小孩 boy1 = new 小孩(ball);
boy1.打气(5);
boy1.打气(5);
boy1.打气(5);
boy1.打气(5);
boy1.打气(5);
}
}
}