事件是对象发送的消息,以发信号通知操作的发生。引发(触发)事件的对象叫做事件发送方。捕获事件并对其作出响应的对象叫做事件接收方。
在事件通信中,事件发送方类不知道哪个对象或方法将接收到(处理)它引发的事件。所需要的是在源和接收方之间存在一个媒介(或类似指针的机制)。.NET Framework 定义了一个特殊的类型(Delegate),该类型提供函数指针的功能。
委托是一个可以对方法进行引用的类。与其他的类不同,委托类具有一个签名,并且它只能对与其签名匹配的方法进行引用。这样,委托就等效于一个类型安全函数指针或一个回调。虽然委托具有许多其他的用途,但这里只讨论委托的事件处理功能。下面的示例显示了事件委托声明。
事件连接:
要在应用程序中使用事件,您必须提供一个事件处理程序(事件处理方法),该处理程序执行程序逻辑以响应事件并向事件源注册事件处理程序。我们将该过程叫做事件连结。
Windows 窗体和 Web 窗体的可视设计器所提供的应用程序快速开发 (RAD) 工具简化(或者说隐藏)了事件连结的细节。
这一过程就是生成以下代码的过程
Private Sub txtClient_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtClient.SelectedIndexChanged
......
end sub
System.Web.UI.WebControls.Button 控件的 Click 事件声明如下。
[C#]
public event EventHandler Click;
[Visual Basic]
Public Event Click As EventHandler
'EventHandler是一个委托类型
要处理该 Click 事件,您必须提供一个签名为 EventHandler 的事件处理程序(事件处理方法)。下面的代码显示了 EventHandler 签名。
[C#]
public delegate void EventHandler(object sender, EventArgs e);
[Visual Basic]
Public Delegate Sub EventHandler(ByVal sender As Object, ByVal e As EventArgs)
'这就是我们通常所说的把方法定义成一个类型
按照约定,.NET Framework 中的事件委托有两个参数:引发事件的源和该事件的数据。
事件数据类从 System.EventArgs 导出。如果事件不生成数据,则它使用 EventArgs 作为事件数据类型。
事件模式
虽然 Windows 窗体和 Web 窗体中事件连结的具体情况有所不同(原因是不同的 RAD 工具提供的支持级别不同),但这两种情况都遵循相同的事件模式,该模式具有以下特征。
引发名为 EventName 事件的类具有以下成员。
[C#]
public event EventNameEventHandler EventName;
[Visual Basic]
Public Event EventName As EventNameEventHandler
EventName 事件的事件委托是 EventNameEventHandler,具有以下签名。
[C#]
public delegate void EventNameEventHandler(object sender, EventNameEventArgs e);
[Visual Basic]
Public Delegate Sub EventNameEventHandler(sender As Object, e As EventNameEventArgs)
要使用 EventName 事件,您的事件处理程序必须与事件委托具有相同的签名。
[C#]
void EventHandler (object sender, EventNameEventArgs e) {}
[Visual Basic]
Sub EventHandler(sender As Object, e As EventNameEventArgs)
示例中的 Click 事件没有任何关联的数据。它对事件数据使用 EventArgs 类,并将 EventHandler 用作委托。具有关联数据的事件使用从事件数据类型中 EventArgs 导出的类以及相应的事件委托类型。例如,如果您要处理 Windows 窗体应用程序中的 MouseUp 事件,事件数据类是 MouseEventArgs,事件委托是 MouseEventHandler。请注意,某些鼠标事件使用事件数据的公共类和公共事件委托,因此命名方案与上面所述的约定不完全匹配。您的事件处理程序必须具有以下签名。
[C#]
void Mouse_Moved(object sender, MouseEventArgs e){}
[Visual Basic] Sub Mouse_Moved(sender As Object, e As MouseEventArgs)