C#事件(event)解析 (转)

大家都知道windows消息处理机制的重要,其实C#事件就是基于windows消息处理 机制的,只是封装的更好,让开发者无须知道底层的消息处理机制,就可以开发出强大的基于事件的应用程序来。

在以往我们编写这类程序中,往往采用等待机制,为了等待某件事情的发生,需要不断地检测某些判断变量,而引入事件编程后,大大简化了这种过程:
- 使用事件,可以很方便地确定程序执行顺序。
- 当事件驱动程序等待事件时,它不占用很多资源。事件驱动程序与过程式程序最大的不同就在于,程序不再不停地检查输入设备,而是呆着不动,等待消息的到来, 每个输入的消息会被排进队列,等待程序处理它。如果没有消息在等待,则程序会把控制交回给操作系统,以运行其他程序。
- 事件简化了编程。操作系统只是简单地将消息传送给对象,由对象的事件驱动程序确定事件的处理方法。操作系统不必知道程序的内部工作机制,只是需要知道如何与对象进行对话,也就是如何传递消息。

  要讲事件,必然要讲到委托(delegate)。

委托(delegate)
委托可以理解成为函数指针,不同的是委托是面向对象,而且是类型安全的。关于委托的理解,可以参考我的另一篇文章《C#委托之个人理解》

事件(event)
  我们可以把事件编程简单地分成两个部分:事件发生的类(书面上叫事件发生器)和事件接收处理的类。事件发生的类就是说在这个类中触发了一个事件,但这个类并不知道哪个个对象或方法将会加收到并处理它触发的事件。所需要的是在发送方和接收方之间存在一个媒介。这个媒介在.NET Framework中就是委托(delegate)。在事件接收处理的类中,我们需要有一个处理事件的方法。好了,我们就按照这个顺序来实现一个捕获键盘按键的程序,来一步一步说明如何编写事件应用程序。

1、首先创建一个自己的EventArgs类。
EventArgs是包含事件数据的类的基类,此类不包含事件数据,在事件引发时不向事件处理程序传递状态信息的事件会使用此类。如果事件处理程序需要状态信息,则应用程序必须从此类派生一个类来保存数据。

因为在我们键盘按键事件中要包含按键信息,所以要派生一个KeyEventArgs类,来保存按键信息,好让后面知道按了哪个键。

None.gif internal class KeyEventArgs : EventArgs
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
private char keyChar;
InBlock.gif
public KeyEventArgs( char keyChar ) : base()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
this.keyChar = keyChar;
ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
public char KeyChar
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
get
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
return keyChar;
ExpandedSubBlockEnd.gif }

ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}

2、再创建一个事件发生的类KeyInputMonitor,这个类用于监控键盘按键的输入并触发一个事件:
None.gif internal class KeyInputMonitor
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
// 创建一个委托,返回类型为void,两个参数
InBlock.gif
public delegate void KeyDown( object sender, KeyEventArgs e );
InBlock.gif
// 将创建的委托和特定事件关联,在这里特定的事件为OnKeyDown
InBlock.gif
public event KeyDown OnKeyDown;
InBlock.gif
InBlock.gif
public void Run()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
bool finished = false;
InBlock.gif
do
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif Console.WriteLine(
"Input a chardot.gif" );
InBlock.gif
string response = Console.ReadLine();
InBlock.gif
InBlock.gif
char responseChar = ( response == "" ) ? ' ' : char.ToUpper( response[0] );
InBlock.gif
switch( responseChar )
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
case 'X':
InBlock.gif finished
= true;
InBlock.gif
break;
InBlock.gif
default:
InBlock.gif
// 得到按键信息的参数
InBlock.gif
KeyEventArgs keyEventArgs = new KeyEventArgs( responseChar );
InBlock.gif
// 触发事件
InBlock.gif
OnKeyDown( this, keyEventArgs );
InBlock.gif
break;
ExpandedSubBlockEnd.gif }

ExpandedSubBlockEnd.gif }
while( !finished );
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}

这里注意OnKeyDown( this, KeyEventArgs );一句,这就是触发事件的语句,并将事件交由KeyDown这个委托来处理,委托指定事件处理方法去处理事件,这就是事件接收方的类的事情了。参数 this是指触发事件的对象就是本身这个对象,keyEventArgs包含了按键信息。

3、最后创建一个事件接收方的类,这个类先产生一个委托实例,再把这个委托实例添加到产生事件对象的事件列表中去,这个过程又叫订阅事件。然后提供一个方法回显按键信息。
None.gif internal class EventReceiver
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
public EventReceiver( KeyInputMonitor monitor )
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
// 产生一个委托实例并添加到KeyInputMonitor产生的事件列表中
InBlock.gif
monitor.OnKeyDown += new KeyInputMonitor.KeyDown( this.Echo );
ExpandedSubBlockEnd.gif }

InBlock.gif
private void Echo(object sender, KeyEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
// 真正的事件处理函数
InBlock.gif
Console.WriteLine( "Capture key: {0}", e.KeyChar );
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}

4、看一下如何调用
None.gif public class MainEntryPoint
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
public static void Start()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
// 实例化一个事件发送器
InBlock.gif
KeyInputMonitor monitor = new KeyInputMonitor();
InBlock.gif
// 实例化一个事件接收器
InBlock.gif
EventReceiver eventReceiver = new EventReceiver( monitor );
InBlock.gif
// 运行
InBlock.gif
monitor.Run();
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}

总结:

C#中使用事件需要的步骤:
1.创建一个委托
2.将创建的委托与特定事件关联(.Net类库中的很多事件都是已经定制好的,所以他们也就有相应的一个委托,在编写关联事件处理程序--也就是当有事件发生时我们要执行的方法的时候我们需要和这个委托有相同的签名)
3.编写事件处理程序
4.利用编写的事件处理程序生成一个委托实例
5.把这个委托实例添加到产生事件对象的事件列表中去,这个过程又叫订阅事件

转载于:https://www.cnblogs.com/zhcw/archive/2011/10/10/2205641.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值