代码改变世界

事件和委托

2008-11-05 16:19  Hundre  阅读(2406)  评论(0编辑  收藏  举报

首先一定要清楚:事件和委托都是一种程序变量的类型,就和int,string等类型一样是用来定义变量的,然后再学习事件和委托是如何使用的

事件是对象发送的消息,以发信号通知操作的发生。操作可能是由用户交互(例如鼠标单击)引起的,也可能是由某些其他的程序逻辑触发的。引发事件的对象称为事件发送方。捕获事件并对其作出响应的对象叫做事件接收方。

在事件通信中,事件发送方类不知道哪个对象或方法将接收到(处理)它引发的事件。所需要的是在源和接收方之间存在一个媒介(或类似指针的机制)。.NET Framework 定义了一个特殊的类型(Delegate),该类型提供函数指针的功能。

委托是可保存对方法的引用的类。与其他的类不同,委托类具有一个签名,并且它只能对与其签名匹配的方法进行引用。这样,委托就等效于一个类型安全函数指针或一个回调。虽然委托具有许多其他的用途,但这里只讨论委托的事件处理功能。一个委托声明足以定义一个委托类。声明提供委托的签名,公共语言运行库提供实现。下面的示例显示了事件委托声明。

public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);


该语法与方法声明的语法相似,但是 delegate 关键字通知编译器 AlarmEventHandler 是一个委托类型。按照约定,

.NET Framework 中的事件委托有两个参数:引发事件的源和该事件的数据。AlarmEventHandler 委托的实例可以绑定到任何一个

与其签名匹配的方法上,例如下面的示例中显示的 WakeMeUp 类的 AlarmRang 方法。

public class WakeMeUp 
{
    // AlarmRang has the same signature as AlarmEventHandler.
    public void AlarmRang(object sender, AlarmEventArgs e)
    {...};
    ...
}

只有当事件生成事件数据时才需要自定义事件委托。许多事件,包括一些用户界面事件(例如鼠标单击)在内,都不生成事件数

据。在这种情况下,类库中为无数据事件提供的事件委托 System.EventHandler 便足够了。其声明如下

delegate void EventHandler(object sender, EventArgs e);
-----------------------------------------------------------------------------------

使用事件

要在应用程序中使用事件,您必须提供一个事件处理程序(事件处理方法),该处理程序执行程序逻辑以响应事件并向事件源注

册事件处理程序。我们将该过程叫做事件连结。Windows 窗体和 Web 窗体的可视设计器所提供的应用程序快速开发 

(RAD) 工具简化(或者说隐藏)了事件连结的详细信息。

事件模式

由于不同 RAD 工具提供不同级别的支持,所以 Windows 窗体和 Web 窗体中的事件连接详细信息是不同的。不过,两个方案

遵循同一事件模式,该模式具有下列特征:

  • 引发名为 EventName 事件的类具有以下成员:
         public event EventNameEventHandler EventName;

EventName 事件的事件委托是 EventNameEventHandler,它具有以下签名:

public delegate void EventNameEventHandler(object sender, EventNameEventArgs e);

要使用 EventName 事件,您的事件处理程序必须与事件委托具有相同签名:

void EventHandler(object sender, EventNameEventArgs e) {}

.NET Framework 中的事件委托命名为 EventNameEventHandler,而文档中的术语“事件处理程序”指的是事件处理方法。

命名方案后的逻辑是 EventNameEventHandler 委托指向实际处理事件的事件处理程序(方法)。

如果事件没有任何关联数据,则引发事件的类使用 System.EventHandler 作为委托,并将 System.EventArgs 作为事件数据。

具有关联数据的事件使用从事件数据类型的 EventArgs 派生的类以及相应的事件委托类型。例如,如果您要处理 Windows 窗

体应用程序中的MouseUp 事件,则事件数据类是 MouseEventArgs,而事件委托是 MouseEventHandler。请注意,

某些鼠标事件使用事件数据的公共类和公共事件委托,因此命名方案与上面所述的约定不完全匹配。对于鼠标事件,事件处理程序0

必须具有以下签名:

void Mouse_Moved(object sender, MouseEventArgs e){}

发送方和事件变量参数向事件处理程序提供有关鼠标事件的详细信息。发送方对象指示引发事件的对象。MouseEventArgs 参数

提供有关引发事件的鼠标移动的详细信息。许多事件源提供有关事件的其他数据,且许多事件处理程序在处理事件时使用事件特定的

数据。