16.4 订阅事件
事件订阅者角色需要订阅事件发布者发布的事件,这样才能在事件发布时接收到消息并做出响应。我们知道,事件事实上是委托类型,因此事件处理方法必须和委托签名相匹配。如果事件使用预定义的委托类型:EventHandler,那么匹配它的事件处理方法如图16-4所示。
图 16-4 匹配EventHandler委托的事件处理方法
有了事件处理方法,就可以订阅事件了,只需要使用加法赋值运算符(+=)即可。假设名为eventSample的对象拥有一个名为PrintComplete的事件,那么订阅事件的代码如下:
eventSample.PrintComplete+=ShowMessage;
另外,还可以使用匿名方法或Lambda表达式进行事件订阅。
使用匿名方法:
eventSample.PrintComplete+=delegate(object sender,EventArgs e)
{
//……
};
使用Lambda表达式:
eventSample.PrintComplete+=(object sender,EventArgs e)=>
{
//……
};
接下来,我们来看一段示例代码,演示注册多个事件处理方法。示例代码模拟这样一种场景:系统在打印完文件后,在屏幕上显示“打印完成”的信息,同时向目标手机发送短消息进行通知,如代码清单16-2所示。
代码清单16-2 事件订阅代码示例
1 using System;
2 namespace ProgrammingCSharp4
3{
4 public class EventSample
5{
6//事件定义
7 public event EventHandler PrintComplete;
8
9 public void OnPrintComplete()
10{
11//判断是否绑定了事件处理方法,null表示没有事件处理方法
12 if(PrintComplete!=null)
13{
14 PrintComplete(this,new EventArgs());
15}
16}
17
18 public static void Main()
19{
20 EventSample eventSample=new EventSample();
21 Printer printer=new Printer(eventSample);
22 eventSample.OnPrintComplete();
23}
24}
25
26 public class Printer
27{
28 public Printer(EventSample eventSample)
29{
30//事件订阅
31 eventSample.PrintComplete+=ShowMessage;
32 eventSample.PrintComplete+=SendSmsToMobile;
33}
34
35//在屏幕上显示信息
36 public void ShowMessage(object sender,EventArgs e)
37{
38 Console.WriteLine(“打印已完成……”);
39}
40
41//模拟发送短消息到手机
42 public void SendSmsToMobile(object sender,EventArgs e)
43{
44 Console.WriteLine(“模拟发送短消息……”);
45}
46}
47}
上述代码运行结果如下:
打印已完成……
模拟发送短消息……
除了订阅事件,也可以实现相反的动作——取消订阅,要从事件取消订阅一个事件处理程序,可以使用(-=)运算符,如下所示:
eventSample.PrintComplete-=ShowMessage;
代码清单16-3 演示了如何取消对于某个事件的订阅。
代码清单16-3 取消事件订阅的代码示例
1 using System;
2 namespace ProgrammingCSharp4
3{
4 public class EventSample
5{
6//事件定义
7 public event EventHandler PrintComplete;
8
9 public void OnPrintComplete()
10{
11//判断是否绑定了事件处理方法,null表示没有事件处理方法
12 if(PrintComplete!=null)
13{
14 PrintComplete(this,new EventArgs());
15}
16}
17
18 public static void Main()
19{
20 EventSample eventSample=new EventSample();
21 Printer printer=new Printer(eventSample);
22 eventSample.OnPrintComplete();//触发事件
23 System.Console.WriteLine(“\n取消订阅SendSmsToMobile处理方法”);
24 printer.Remove(eventSample);//取消订阅
25 eventSample.OnPrintComplete();//触发事件
26}
27}
28
29 public class Printer
30{
31 public Printer(EventSample eventSample)
32{
33//事件订阅
34 eventSample.PrintComplete+=ShowMessage;
35 eventSample.PrintComplete+=SendSmsToMobile;
36}
37
38//从事件中取消订阅SendSmsToMobile方法
39 public void Remove(EventSample eventSample)
40{
41 eventSample.PrintComplete-=SendSmsToMobile;
42}
43
44//在屏幕上显示信息
45 public void ShowMessage(object sender,EventArgs e)
46{
47 Console.WriteLine(“打印已完成……”);
48}
49
50//模拟发送短消息到手机
51 public void SendSmsToMobile(object sender,EventArgs e)
52{
53 Console.WriteLine(“模拟发送短消息……”);
54}
55}
56}
运行结果为:
打印已完成……
模拟发送短消息……
取消订阅SendSmsToMobile处理方法
打印已完成……