16.4 订阅事件

事件订阅者角色需要订阅事件发布者发布的事件,这样才能在事件发布时接收到消息并做出响应。我们知道,事件事实上是委托类型,因此事件处理方法必须和委托签名相匹配。如果事件使用预定义的委托类型:EventHandler,那么匹配它的事件处理方法如图16-4所示。

16.4 订阅事件 - 图1

图 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处理方法

打印已完成……