事件和委托学习
2007-01-19 17:25
435 查看
事件就是发生的一件事情。把事件信息通知给其它对象的对象称为事件发布方(事件源)。对象可以把自己注册到事件中,该对象称为事件的订户(事件的注册用户),事件可以有一个或多个注册用户。事件只把事件信息通知给所注册的用户。
参考:http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/csref/html/vclrfeventpg.asp
C#中的事件需要借助于委托。它们使用委托调用预订了该事件的用户中的方法。当发布方引发事件时,可能会调用许多委托(视预订该事件的对象数量而定)。
定义事件时,首先由发布方定义委托,然后才能定义事件。事件取决于委托。如:
先定义一个委托delegateMe:
PublicdelegatevoiddelegateMe(objectparam);
然后根据委托delegateMe定义事件eventMe:
PubliceventdelegateMeeventMe;
.net中事件的原形如下:
[align=left][attributes][modifiers]eventtypedeclarator;[/align]
[align=left][attributes][modifiers]eventtypemember-name{accessor-declarations};[/align]
其中:
attributes(可选)
可选的声明信息。有关属性和属性类的更多信息,请参见C#属性。
modifiers(可选)
可选的修饰符,包括:abstract,new,override,static,virtual,extern,四个访问修饰符之一
type
希望与此事件关联的delegate。
declarator
事件名。
member-name
事件名。
accessor-declarations(可选)
访问器的声明,用于添加或移除客户代码中的事件处理程序。访问器函数为add和remove。只定义一个而不定义另一个是错误的。
[align=left]为了创建并使用C#事件,必须采取以下步骤:[/align]
[align=left]1.创建或标识一个委托。如果正在定义自己的事件,还必须确保有与事件关键字一起使用的委托。如果已经预定义了事件(例如在.NETFramework中),则事件的使用者只需要知道委托的名称。[/align]
[align=left]2.创建一个类,包含:[/align]
[align=left]a.从委托创建的事件。[/align]
[align=left]b.(可选)验证用event关键字声明的委托实例是否存在的方法。否则,该逻辑必须放置在引发此事件的代码中。[/align]
[align=left]c.调用此事件的方法。这些方法可以重写一些基类功能。[/align]
[align=left]此类定义事件。[/align]
[align=left]3.定义一个或多个将方法连接到事件的类。所有这些类都包括:[/align]
[align=left]·使用+=运算符和-=运算符将一个或多个方法与基类中的事件关联。[/align]
[align=left]·将与事件关联的方法的定义。[/align]
[align=left]4.使用此事件:[/align]
[align=left]·创建包含事件声明的类对象。[/align]
[align=left]·使用定义的构造函数,创建包含事件定义的类对象。[/align]
[align=left]有关事件的更多信息,请参见MSDN:[/align]
[align=left]·10.7事件[/align]
[align=left]·事件教程[/align]
[align=left]·事件和委托[/align]
[align=left][/align]
net定义事件需要一些约定束成的规则:
事件功能是由三个互相联系的元素提供的:提供事件数据的类、事件委托和引发事件的类。.NETFramework具有命名与事件相关的类和方法的约定。如果想要您的类引发一个名为EventName的事件,您需要以下元素。
持有事件数据的类,名为EventNameEventArgs。该类必须从
System.EventArgs导出。
事件的委托,名为EventNameEventHandler。
引发事件的类。该类必须提供:
事件声明。
引发事件的方法,名为OnEventName。
.NETFramework类库或第三方类库中可能已经定义了事件数据类和事件委托类。在这种情况下,您就不需要定义这些类了。
如果您不熟悉.NETFramework中事件的委托模型,请参见事件和委托。
1.声明事件
publiceventEventNameEventHandlerEventName;
2.声明代理;
publicdelegatevoidEventNameEventHandler(objectsender,EventNameEventArgse);
3.定义方法
voidOnEventHandler(objectsender,EventNameEventArgse){}
4.触发事件(关联事件)
例如,在服务端控件的this.EventName+=newEventNameEventHandler(this.OnEventHandler);
示例:
[align=left]usingSystem;[/align]
[align=left][/align]
[align=left]namespaceevent_test[/align]
[align=left]{[/align]
[align=left]//[/align]
[align=left]classDelegateEvent[/align]
[align=left]{[/align]
[align=left]publicdelegatevoidMyDelegate();[/align]
[align=left]publiceventMyDelegateNotifyEveryOne;[/align]
[align=left]//定义一个可能引发事件的方法[/align]
[align=left]publicvoidNotify()[/align]
[align=left]{[/align]
[align=left]if(NotifyEveryOne!=null)[/align]
[align=left]{[/align]
[align=left]System.Console.WriteLine("引发了事件!");[/align]
[align=left][/align]
[align=left]//触发事件,与方法的使用方式相同。[/align]
[align=left]NotifyEveryOne();//事件通知委托对象,委托对象调用实例化时作为参数的方法.[/align]
[align=left]}[/align]
[align=left]}[/align]
[align=left]}[/align]
[align=left][/align]
[align=left]classclsA[/align]
[align=left]{[/align]
[align=left]publicvoidDispMethodA()[/align]
[align=left]{[/align]
[align=left]System.Console.WriteLine("已经把事件NotifyEveryOne通知到ClassA!");[/align]
[align=left]}[/align]
[align=left]}[/align]
[align=left][/align]
[align=left]classclsB[/align]
[align=left]{[/align]
[align=left]publicvoidDispMethodB()[/align]
[align=left]{[/align]
[align=left]System.Console.WriteLine("已经把事件NotifyEveryOne通知到ClassB!");[/align]
[align=left]}[/align]
[align=left]}[/align]
[align=left][/align]
[align=left]classclsTest[/align]
[align=left]{[/align]
[align=left]///<summary>[/align]
[align=left]///应用程序的主入口点。[/align]
[align=left]///</summary>[/align]
[align=left][STAThread][/align]
[align=left]staticvoidMain(string[]args)[/align]
[align=left]{[/align]
[align=left]//首先实例化一个事件源对象。[/align]
[align=left]DelegateEventeventSource=newDelegateEvent();[/align]
[align=left][/align]
[align=left]//实例化事件的订户[/align]
[align=left]clsAobjA=newclsA();[/align]
[align=left]clsBobjB=newclsB();[/align]
[align=left][/align]
[align=left]//使用委托把对象及其方法注册到事件中[/align]
[align=left]eventSource.NotifyEveryOne+=newevent_test.DelegateEvent.MyDelegate(objA.DispMethodA);[/align]
[align=left]eventSource.NotifyEveryOne+=newevent_test.DelegateEvent.MyDelegate(objB.DispMethodB);[/align]
[align=left][/align]
[align=left]eventSource.Notify();[/align]
[align=left]}[/align]
[align=left][/align]
[align=left]}[/align]
[align=left]}[/align]
[align=left][/align]
[align=left]再续:[/align]
理解一:事件委托的概念
.NET框架的事件委托遵循特定的签名和命名约定。这种约定依赖于可视化设计工具,为客户端代码提供了一致性的模型。为了理解这种约定,下面来看看.NET框架中一个常见的可访问事件委托System.EventHandler:
publicdelegatevoidEventHandler(objectsender,EventArgse);
下面是一些特定的事件委托签名约定:
◎事件委托的返回类型是void
◎一个事件委托带有两个参数。第一个参数是object类型,表示事件的发送者。第二个参数
描述事件的数据,是由System.EventArgs派生出的类的实例。
应该根据.NET框架的命名约定来给事件数据类和事件委托命名。事件数据类由事件名再添加
后缀EventArgs构成,如MonthChangeEventArgs。
事件委托由事件名再添加EventHandler后缀构成,如MonthChangeEventHandler。事件委托
用事件处理程序(EventHandler)命名是因为她们将绑定到处理事件的方法上。
理解二:Wiring事件
将事件处理程序和事件相关联的过程(添加委托给invocation列表)叫做事件布线(eventwiring).
而从事件中删除事件处理程序的过程叫做事件撤线(eventunwring)。
在C#中,对于一个事件的布线和撤线事件处理程序的语法如下:
button.Click+=newEventHandler(this.Button_Clicked);
button.Click-=newEventHandler(this.Button_Clicked);
这里,button是Button控件的一个实例,并建立于具有Button_Clicked方法的类中,该方法处理按钮的Click事件。
理解三:事件委托的实现
为了在类中实现事件,需要一个事件数据的类、事件委托、在类中拥有invocation列表的委托成员,以及一个发布事件通知的方法。
具体实现过程如下:
1)如果类没有任何关联的事件数据,对事件数据使用EventArgs类。或者可以使用其他事先已经存在的事件数据类。如果不存在一个合适的事件数据类,则定义一个事件来包含事件数据。这个类必须从System.EventArgs中派生。按照规则它的名字应该是事件名加上EventArgs得到。例如,AdCreatedEventArgs,MonthChangedEventArgs.
下面的代码声明了一个事件数据类:
publicclassLowChargeEventArgs:EventArgs{...}
2)如果事件没有关联数据,使用第一步的EventArgs,用System.EventHandler作为事件委托或者使用能匹配事件的预先存在的其他委托。如果不存在一个合适的事件委托,则定义一个事件委托,该委托的第二个参数具备来自第一步的事件数据类的类型。根据规则,事件委托的名字是在事件后附加EventHandler.例如,AdCreateEventHandler,MonthChangedEventHandler。下面的代码用来定义事件委托:
publicdelegatevoidLowChargeEventHandler(objectsender,LowChargeEventArgse);
3)在类里,用event关键字定义事件成员。将事件名传递给事件成员。成员的类型是第二步中事件委托的类型。
如下面的例子:
publiceventLowChargeEventHandlerLowCharge;
事件成员包含订阅事件的委托的列表。当调用这个成员时,它通过调用委托来分配事件。
4)在类里,定义一个受保护的虚拟方法,在检查是否有事件监听器存在之后调用事件委托。其参数就是第一步中定义的事件数据×EventArgs。方法的名字是在事件名前加上前缀On。例如:
protectedvirtualvoidOnLowCharge(LowChargeEventArgse){
if(LowCharge!=null){
LowCharge(this,e);
}
}
参考:
C#中的事件需要借助于委托。它们使用委托调用预订了该事件的用户中的方法。当发布方引发事件时,可能会调用许多委托(视预订该事件的对象数量而定)。
定义事件时,首先由发布方定义委托,然后才能定义事件。事件取决于委托。如:
先定义一个委托delegateMe:
PublicdelegatevoiddelegateMe(objectparam);
然后根据委托delegateMe定义事件eventMe:
PubliceventdelegateMeeventMe;
.net中事件的原形如下:
[align=left][attributes][modifiers]eventtypedeclarator;[/align]
[align=left][attributes][modifiers]eventtypemember-name{accessor-declarations};[/align]
其中:
attributes(可选)
可选的声明信息。有关属性和属性类的更多信息,请参见
modifiers(可选)
可选的修饰符,包括:
type
希望与此事件关联的
declarator
事件名。
member-name
事件名。
accessor-declarations(可选)
访问器的声明,用于添加或移除客户代码中的事件处理程序。访问器函数为add和remove。只定义一个而不定义另一个是错误的。
[align=left]为了创建并使用C#事件,必须采取以下步骤:[/align]
[align=left]1.创建或标识一个委托。如果正在定义自己的事件,还必须确保有与事件关键字一起使用的委托。如果已经预定义了事件(例如在.NETFramework中),则事件的使用者只需要知道委托的名称。[/align]
[align=left]2.创建一个类,包含:[/align]
[align=left]a.从委托创建的事件。[/align]
[align=left]b.(可选)验证用event关键字声明的委托实例是否存在的方法。否则,该逻辑必须放置在引发此事件的代码中。[/align]
[align=left]c.调用此事件的方法。这些方法可以重写一些基类功能。[/align]
[align=left]此类定义事件。[/align]
[align=left]3.定义一个或多个将方法连接到事件的类。所有这些类都包括:[/align]
[align=left]·使用+=运算符和-=运算符将一个或多个方法与基类中的事件关联。[/align]
[align=left]·将与事件关联的方法的定义。[/align]
[align=left]4.使用此事件:[/align]
[align=left]·创建包含事件声明的类对象。[/align]
[align=left]·使用定义的构造函数,创建包含事件定义的类对象。[/align]
[align=left]有关事件的更多信息,请参见MSDN:[/align]
[align=left]·
[align=left]·
[align=left]·
[align=left][/align]
net定义事件需要一些约定束成的规则:
事件功能是由三个互相联系的元素提供的:提供事件数据的类、事件委托和引发事件的类。.NETFramework具有命名与事件相关的类和方法的约定。如果想要您的类引发一个名为EventName的事件,您需要以下元素。
持有事件数据的类,名为EventNameEventArgs。该类必须从
System.EventArgs导出。
事件的委托,名为EventNameEventHandler。
引发事件的类。该类必须提供:
事件声明。
[C#]publiceventEventNameEventHandlerEventName;
引发事件的方法,名为OnEventName。
.NETFramework类库或第三方类库中可能已经定义了事件数据类和事件委托类。在这种情况下,您就不需要定义这些类了。
如果您不熟悉.NETFramework中事件的委托模型,请参见
1.声明事件
publiceventEventNameEventHandlerEventName;
2.声明代理;
publicdelegatevoidEventNameEventHandler(objectsender,EventNameEventArgse);
3.定义方法
voidOnEventHandler(objectsender,EventNameEventArgse){}
4.触发事件(关联事件)
例如,在服务端控件的this.EventName+=newEventNameEventHandler(this.OnEventHandler);
示例:
[align=left]usingSystem;[/align]
[align=left][/align]
[align=left]namespaceevent_test[/align]
[align=left]{[/align]
[align=left]//[/align]
[align=left]classDelegateEvent[/align]
[align=left]{[/align]
[align=left]publicdelegatevoidMyDelegate();[/align]
[align=left]publiceventMyDelegateNotifyEveryOne;[/align]
[align=left]//定义一个可能引发事件的方法[/align]
[align=left]publicvoidNotify()[/align]
[align=left]{[/align]
[align=left]if(NotifyEveryOne!=null)[/align]
[align=left]{[/align]
[align=left]System.Console.WriteLine("引发了事件!");[/align]
[align=left][/align]
[align=left]//触发事件,与方法的使用方式相同。[/align]
[align=left]NotifyEveryOne();//事件通知委托对象,委托对象调用实例化时作为参数的方法.[/align]
[align=left]}[/align]
[align=left]}[/align]
[align=left]}[/align]
[align=left][/align]
[align=left]classclsA[/align]
[align=left]{[/align]
[align=left]publicvoidDispMethodA()[/align]
[align=left]{[/align]
[align=left]System.Console.WriteLine("已经把事件NotifyEveryOne通知到ClassA!");[/align]
[align=left]}[/align]
[align=left]}[/align]
[align=left][/align]
[align=left]classclsB[/align]
[align=left]{[/align]
[align=left]publicvoidDispMethodB()[/align]
[align=left]{[/align]
[align=left]System.Console.WriteLine("已经把事件NotifyEveryOne通知到ClassB!");[/align]
[align=left]}[/align]
[align=left]}[/align]
[align=left][/align]
[align=left]classclsTest[/align]
[align=left]{[/align]
[align=left]///<summary>[/align]
[align=left]///应用程序的主入口点。[/align]
[align=left]///</summary>[/align]
[align=left][STAThread][/align]
[align=left]staticvoidMain(string[]args)[/align]
[align=left]{[/align]
[align=left]//首先实例化一个事件源对象。[/align]
[align=left]DelegateEventeventSource=newDelegateEvent();[/align]
[align=left][/align]
[align=left]//实例化事件的订户[/align]
[align=left]clsAobjA=newclsA();[/align]
[align=left]clsBobjB=newclsB();[/align]
[align=left][/align]
[align=left]//使用委托把对象及其方法注册到事件中[/align]
[align=left]eventSource.NotifyEveryOne+=newevent_test.DelegateEvent.MyDelegate(objA.DispMethodA);[/align]
[align=left]eventSource.NotifyEveryOne+=newevent_test.DelegateEvent.MyDelegate(objB.DispMethodB);[/align]
[align=left][/align]
[align=left]eventSource.Notify();[/align]
[align=left]}[/align]
[align=left][/align]
[align=left]}[/align]
[align=left]}[/align]
[align=left][/align]
[align=left]再续:[/align]
理解一:事件委托的概念
.NET框架的事件委托遵循特定的签名和命名约定。这种约定依赖于可视化设计工具,为客户端代码提供了一致性的模型。为了理解这种约定,下面来看看.NET框架中一个常见的可访问事件委托System.EventHandler:
publicdelegatevoidEventHandler(objectsender,EventArgse);
下面是一些特定的事件委托签名约定:
◎事件委托的返回类型是void
◎一个事件委托带有两个参数。第一个参数是object类型,表示事件的发送者。第二个参数
描述事件的数据,是由System.EventArgs派生出的类的实例。
应该根据.NET框架的命名约定来给事件数据类和事件委托命名。事件数据类由事件名再添加
后缀EventArgs构成,如MonthChangeEventArgs。
事件委托由事件名再添加EventHandler后缀构成,如MonthChangeEventHandler。事件委托
用事件处理程序(EventHandler)命名是因为她们将绑定到处理事件的方法上。
理解二:Wiring事件
将事件处理程序和事件相关联的过程(添加委托给invocation列表)叫做事件布线(eventwiring).
而从事件中删除事件处理程序的过程叫做事件撤线(eventunwring)。
在C#中,对于一个事件的布线和撤线事件处理程序的语法如下:
button.Click+=newEventHandler(this.Button_Clicked);
button.Click-=newEventHandler(this.Button_Clicked);
这里,button是Button控件的一个实例,并建立于具有Button_Clicked方法的类中,该方法处理按钮的Click事件。
理解三:事件委托的实现
为了在类中实现事件,需要一个事件数据的类、事件委托、在类中拥有invocation列表的委托成员,以及一个发布事件通知的方法。
具体实现过程如下:
1)如果类没有任何关联的事件数据,对事件数据使用EventArgs类。或者可以使用其他事先已经存在的事件数据类。如果不存在一个合适的事件数据类,则定义一个事件来包含事件数据。这个类必须从System.EventArgs中派生。按照规则它的名字应该是事件名加上EventArgs得到。例如,AdCreatedEventArgs,MonthChangedEventArgs.
下面的代码声明了一个事件数据类:
publicclassLowChargeEventArgs:EventArgs{...}
2)如果事件没有关联数据,使用第一步的EventArgs,用System.EventHandler作为事件委托或者使用能匹配事件的预先存在的其他委托。如果不存在一个合适的事件委托,则定义一个事件委托,该委托的第二个参数具备来自第一步的事件数据类的类型。根据规则,事件委托的名字是在事件后附加EventHandler.例如,AdCreateEventHandler,MonthChangedEventHandler。下面的代码用来定义事件委托:
publicdelegatevoidLowChargeEventHandler(objectsender,LowChargeEventArgse);
3)在类里,用event关键字定义事件成员。将事件名传递给事件成员。成员的类型是第二步中事件委托的类型。
如下面的例子:
publiceventLowChargeEventHandlerLowCharge;
事件成员包含订阅事件的委托的列表。当调用这个成员时,它通过调用委托来分配事件。
4)在类里,定义一个受保护的虚拟方法,在检查是否有事件监听器存在之后调用事件委托。其参数就是第一步中定义的事件数据×EventArgs。方法的名字是在事件名前加上前缀On。例如:
protectedvirtualvoidOnLowCharge(LowChargeEventArgse){
if(LowCharge!=null){
LowCharge(this,e);
}
}
相关文章推荐
- 学习笔记之---C#中的委托与事件
- C#学习笔记19-委托和事件
- C#学习笔记(三)—–C#高级特性中的委托与事件(下)
- C#事件 委托 学习笔记
- C#委托、事件学习之(一)——委托事件描述
- C# 委托 事件 学习 以及 小DEMO
- 委托与事件学习笔记1---什么是委托?
- 学习随笔-1 委托和事件
- 委托、事件与匿名方法 — 学习委托最好的资料
- 学习:C# 中的委托和事件(转)
- C# 委托、Lambda表达式和事件——学习总结
- 事件和委托学习小练习
- 学习系列之委托与事件
- C#高级编程 (第六版) 学习 第七章:委托和事件
- C#中的委托、事件学习笔记
- c#的委托和事件的实例学习
- 委托与事件学习笔记1---什么是委托?
- c#中的委托和事件详细学习【分6页学习】
- C#学习之初步理解委托、事件、匿名方法和Lambda
- unity学习之委托与事件的初步应用