深入浅出话事件(下)
深入浅出话事件(下)二.事件的由来???????在传统的面向对象的概念中是没有“事件”这个概念的。传统的面向对象概念中只有数据(Data,也称为field、域、成员变量)和方法(Method,也就是成员函数、function)。如果我没记错,那么事件这个概念最早出现在微软的COM技术中,又因为VB是基于ActiveX(COM的一种)的,所以“事件”这一概念便通过VB广而推之、为众多程序员所熟知并使用的——我就是其中的一员。 ???????.NET Framework实际上是对COM的更高层级的封装——要知道,早先.NET Framework这个名字没有出来之前,它叫“COM3”来着——自然就保留了对事件的支持。 三.事件的意义???????《进化论》说:“物竞天择,合理即存在。” ???????微软说:“我是老大,存在即合理!” ???????姑且不管微软是不是在耍大牌、搞霸权——事件的存在的确给程序的开发带来了很多方便。从设计层面上讲,它使程序在逻辑思维方面变得简洁清晰、便于维护;从技术层面上讲,它把坚涩难懂的Windows消息传递机制包装的漂漂亮亮,极大地降低了程序员入职的门槛儿。 从软件工程的角度上来看,事件是一种通知机制,是类与类之间保持同步的途径。 问曰:什么同步? 答曰:消息同步! 四.事件的本质——对消息传递的封装事件可以被激发(Fire,也有称为“引发”的),一个类所包含的成员事件可以在多种情况下被激发。最典型的:一个按钮的Click事件,可以由用户使用鼠标来激发它,也可以由测试这个软件的另一个软件通过Win32 API函数来激发它。 我们来简要讨论一下这个Click事件: 其实,如果你了解Win32的本质,你应该明白用户是不可能直接接触到某个控件的。表面上看,的确是用户用鼠标点击了一下按钮。而实际上,当用户按下鼠标左键的时候是通过鼠标向Windows操作系统发送了一个“左键单击[x,y]点”消息,然后Windows再根据[x,y]的位置把这个消息分配(路由)给应该接收它的控件——这就是Windows的消息传递/路由机制。 同理,当你移动鼠标的时候,看似好像指针在随你的意愿移动,而实际上是你的鼠标在以每秒钟几百次的频率把当前位置汇报给Windows操作系统,然后Windows再把一个漂亮的指针“画”在屏幕上给你看——哈哈,我们都被骗了! 然而这些内容对于C#程序员都是不可见的——都被封装成了“事件”。因此,从Windows系统的机理上讲,事件机制就是对Windows消息传递机制的包装。 ???????下面的代码是对Visual Studio 2005自动生成的WinForm程序的一个模拟。读懂之后,大家可以自己写一个WinForm,对照剖析其中的机理。 代码: //============水之真谛============// 1.????????要想引用using?System.Drawing;?using?System.Windows.Forms;这两个Namespace,首先要手动添加对System.Drawing和System.Windows.Forms两个程序集(Assembly)的引用。 2.????????EmulateForm类是自定义的,注意,它派生自Form类。为了清晰起见,我已经把代码简化到了几乎最简……只有两个成员变量。myButton是Button类的一个实例;myTextBox是TextBox类的一个实例。EmulateForm类的成员方法private?voidInitializeComponent()完全是对真正WinForm程序的模仿,在它的函数体里,对成员变量进行了实例化、初始化(比如确定大小和位置),并将它们加入了窗体的Controls数组里。这个函数将在EmulateForm的构造函数里被执行。 3.????????本例中最重要的部分就是对myButton的初始化。注意这句:myButton.Click +=?new?EventHandler(myButton_Click); 4.????????详细剖析Button.Click事件:首先,事件都是基于委托的,那么myButton.Click事件是基于哪个委托呢?通过查找MSDN,你可以发现myButton.Click是继承自Control类,并基于EventHandler这一委托——下面是EventHandler委托的声明 5.????????void?myButton_Click(object?sender,?EventArgs?e)是EmulateForm类对myButton.Click事件的响应函数(也称事件处理器,Eventhandler)。注意它的参数列表,是不是与EventHandler委托一致啊:p 6.????????主程序没什么好说的了——new一个EmulateForm的实例出来,用Application.Run方法执行程序就好了。 7.????????顺便在这里做一个纠偏:上面已经解释过sender是什么了——它是消息的发送者。我屡次在一些书中发现诸如“事件发送者”这类的话,这是不对的!你想啊,事件只能引发、激发、发生,怎么可能“发送”呢?不合逻辑…… 作业1: ?????? ???????建立一个WinForm程序,如图。包含1个Panel,3个TextBox,1个Button。 要求: 1.????当鼠标在Panel里滑动时,textBox1和textBox2分别显示鼠标当前的X和Y。 2.????当鼠标点击按钮时,textBox3要显示Hello Events World!字样。 提示: 1.????留心MouseMove事件的e 2.????留心Visual Studio 2005使用的是C# 2.0,并且使用partial关键字将Form1类的代码分别存储在了Form1.cs和Form1.Designer.cs两个文件里。 作业2: ???????将《深入浅出话事件(上)》中嘎子炸鬼子的程序升级至使用事件的版本。(代码我将在以后的日子里给出)。 ? OVER ? 法律声明:本文章受到知识产权法保护,任何单位或个人若需要转载此文,必需保证文章的完整性(未经作者许可的任何删节或改动将视为侵权行为)。若您需要转载,请务必注明文章出处为CSDN以保障网站的权益;请务必注明文章作者为刘铁猛,并向bladey@tom.com发送邮件,标明文章位置及用途。转载时请将此法律声明一并转载,谢谢! (编辑:北几岛) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |