事件是类在发生其关注的事情时用来提供通知的一种方式。例如,封装用户界面控件的类可以定义一个在用户单击该控件时发生的事件。控件类不关心单击按钮时发生了什么,但它需要告知派生类单击事件已发生。然后,派生类可选择如何响应。
事件使用委托来为触发时将调用的方法提供类型安全的封装。委托可以封装命名方法和匿名方法。
CLR类型中可以定义的一个要素,定义了事件成员的类型允许类型或类型的实例在某些特定的事情发生时通知其他对象。最常见的如Button类的Click事件,当单击Button对象时,应用程序其他的一个或多个对象可能希望能收到关于这个事件的通知,从而执行一些动作(响应事件)。
事件实用的是发布者\订阅者机制,发布者在事件发生时发出通知,订阅者收到通知之后执行一些响应操作。CLR的事件模型建立在委托(Delegate)机制上。委托是一种类型安全的回调方法(callback method)的方式。CLR中类型的静态方法或者对象的实例方法可以订阅\注销类型事件。事件其实就是一种委托,订阅者实现的时候将委托定义的形式的方法实现,再将发布者的委托实例上+=一下把定义的处理方法加进去,事件一来发布者调用委托实例执行,那么订阅了该事件的对象定义的处理方法都能执行了。
设计一个对外提供事件的类型步骤:
step1 定义一个类型用于存放所有需要发送给事件订阅者的附加信息,应该继承自System.EventArgs;如果不传递额外信息,直接使用EventArgs.Empty,无需定义新的EventArgs对象;
step2 定义事件成员,遵循事件定义模式,如
public event EventHandler<SomeEventArgs> eventname;
而EventHandler的原型为
public delegate void EventHandler<TEventArgs>
(Object sender,TEventArgs e) where TEventArgs:EventArgs
所以根据委托的使用形式,事件必须定义为void MethodName(Object sender, SomeEventArgs e)。
step3 定义一个负责引发事件的方法来通知订阅者事件已经发生
一般定义为Oneventname(SomeEventArgs e)
如邮件通知事件:
protected void OnNewMail(NewMailEventArgs e)
{
EventHandler<NewMailEventArgs> temp=NewMail;
if(temp!=null) temp(this,e);
}
将事件成员定义为一个临时变量在于线程安全的考虑。
step4 定义一个方法,将输入转化为期望事件
发布者中要实现事件对应的动作发生之后,要引发事件通知程序即step4中定义的方法。
事件具有以下特点:
事件是类用来通知对象需要执行某种操作的方式。
尽管事件在其他时候(如信号状态更改)也很有用,事件通常还是用在图形用户界面中。
事件通常使用委托事件处理程序进行声明。
事件可以调用匿名方法来替代委托。有关更多信息,请参见匿名方法。
such as:
通知:
public event System.EventHandler ComNavCommandEvent;//定义
CommNav1.Item = GetLeftItem(strCurPar);
CommNav1.ComNavCommandEvent += new EventHandler(CommNav1_ComNavCommandEvent);
void CommNav1_ComNavCommandEvent(object sender, EventArgs e)
{
ManageLeft(CommNav1.CommandName, CommNav1.CommandArgument);
}
事件具体动作:
public void ManageLeft(string strCommandName, string strCommandArgument) {
int intStart = strCurUrl.LastIndexOf('/');
int intEnd = strCurUrl.LastIndexOf('.');
string strTemp = strCurUrl.Substring(intStart+1, intEnd - intStart-1);
switch (strCommandName)
{
case "All Blogs":
Response.Redirect(strTemp + ".aspx?MemberID="+strCurUserID);
break;
case "TypeID":
Response.Redirect(strTemp + ".aspx?TypeID=" + strCommandArgument+"&MemberID="+strCurUserID);
break;
case "Folder":
Response.Redirect(strTemp + ".aspx?FolderID=" + strCommandArgument);
break;
}
}