Henry的VB.NET之旅(十二)—事件驱动

Henry的VB.NET之旅(十二)—事件驱动

韩睿

“可视继承原来这么方便!”我心中默默地感叹一声。一会儿之后,我抬头扫了一眼屏幕上的代码后,突然发现了一个新问题,按钮的单击事件程序现在已经变成了:

VB.NET程序
VB程序

Private Sub btnProtected_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProtected.Click

MsgBox("派生的保护按钮")

End Sub

Private Sub Command1_Click()

……

End Sub

而原来的VB程序是那么的简单。现在的参量Sender和e是干什么用的?那个Handles又是什么东东?还好有老师,我立刻起身,厚着脸把大李请过来,把疑问一一说给他听。

大李推了推眼镜,反问我道:“你应该对Windows编程中的事件驱动程序设计很熟悉吧?”(注:此处的Windows是指Win9X及其以上的操作系统)

“是呀!”看来反问是大李授课的开篇词了,但我也只好先往他的圈套里跳,“事件驱动就是说应用程序的执行流程是由外界发生的事件所确定的。也就是接受到任务才工作的模式。事件就是一个信号,它告知应用程序有重要情况要发生。实际上的执行情况是,各个应用程序把负责不同工作的对象在其运行期间送入Windows操作系统,让这些对象等待Windows产生的事件,然后加以处理。”

“VB程序员一般也只需要象你这样理解就行了。”大李的话真让我触动,“应该说是Windows先产生消息,应用程序中的窗口程序window procedure能接收来自windows的消息,并将其转化为事件,这个我们以后再说。现在来看看事件驱动程序的组成,主要是有事件、对象和事件处理程序三个要素。对象就是完成任务的主体,比如你说的Button1;事件么,就是对象要执行的任务,比如单击,就是click事件;那么事件处理程序就是Button1_Click这段程序了。”

“这个我知道呀!我只是想问一下Sender……”我疑惑地回应道。

大李哥摇摇手,打断了我的话。“如果你真正清楚事件驱动的话,就明白了。你看一下,Sender是什么类型的变量?”

“object呀!”我无奈地问道着,“但是,……”我隐约感觉到了什么。

大李微笑着说,“sender as object,就一语道破它的来源与用途。object是支持 .NET 框架类层次结构中的所有类,并为派生类提供低级别服务。这是 .NET 框架中所有类的最终超类;它是类型层次结构的根。一般来说,sender在形参中表示引发事件的源头,就是我刚才所说的三要素中的‘对象’。如果在控件引发的事件中写代码的话,一般都不需要再重新指派,因为它已经默认为是该控件了。当自己写代码来调用某事件程序时,就要注明sender是何物了。”

“也就是说,sender是提供给在事件处理程序代码内部或外部进行调用的吗?”我仍有点不明白。

“可以这样说,你难道看不出VB.NET提供给我们的是更全面、更直接的控制吗?再说e,表示的是事件数据,就是一个事件激发所需要的状态信息。在事件引发时不向事件处理程序传递状态信息的事件会将e设为Eventargs。如果事件处理程序需要状态信息,则应用程序必须从此类派生一个类来保存数据。比如Mousedown事件,系统需要判断mouse的位置、判断是左中右哪个键点击了、判断点击了几下等等,因此该e就必需是System.Windows.Forms.MouseEventArgs类的实例。”大李继续解说着。

“哦,也就是说e是和事件密切相关的喽?”我开始用实际操作来证实一下,我在代码窗口的“类名”下拉列表中选择了Button1,在其右边的“方法名称”下拉列表中选择了MosueDown方法,出现的就是Button1.MouseDown事件处理程序代码段:

Private Sub Button1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseDown

End Sub

果然,看到e的类型变为System.Windows.Forms.MouseEventArgs。我在代码段内写下e,然后在其后打一个点,出现了一个智能感知菜单(如图1所示):

与button1.click事件相比,button1.Mosuedown事件中的e的属性和方法多出了五个描述事件特征的属性,见表1所述。

Button
获取曾按下的是哪个鼠标按钮。

Clicks
获取按下并释放鼠标按钮的次数。

Delta
获取鼠标轮已转动的制动器数的有符号计数。制动器是鼠标轮的一个凹口。

X
获取鼠标单击的 x 坐标。

Y
获取鼠标单击的 y 坐标。

表1 多出的e的属性

“我明白了,那么Handles关键字是不是就是用于声明代码是要处理哪个事件的处理过程呢?”我终于开了点窍。

“是的,可不要小看Handles,好好利用它,你的程序会变得简洁和灵活。”大李边说边给我写了一段代码:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _

Handles Button1.Click, Button2.Click

Select Case sender.name

Case "Button1"

MsgBox("你点击的是button1")

Case "Button2"

MsgBox("你点击的是button2")

End Select

End Sub

“在Handles后面写了两个事件的声明,就可以在同一段代码中对两个对象进行控制。另外,利用Sender和e我们还可以更方便地构建与调用自己的事件处理程序。“大李边写边说。

“是吗?怎么实现?”我不由被激发出了浓浓的兴趣。

(未完待续)

时间: 2024-11-08 18:58:09

Henry的VB.NET之旅(十二)—事件驱动的相关文章

Henry的VB.NET之旅(十四)—动态关联事件与处理程序

程序|动态 Henry的VB.NET之旅(十四)-动态关联事件与处理程序 韩睿 "要解释新的事件处理程序的方法,我们需要先说几个重要的问题."大李开始严肃起来,我也只得挪动一下身子,表现出正襟危坐的架势. "我们首先讨论一下事件是怎么产生的.事件是对象发送的消息,以发信号通知操作的发生.操作可能是由用户交互,例如鼠标单击引起的,也可能是由某些其他的程序逻辑触发的.引发事件的对象叫做事件发送方(啊,听到这,Henry突然明白了事件处理程序中的第一个参量为什么叫Sender了,就

Henry的VB.NET之旅(十五)—动态事件处理方法

动态 Henry的VB.NET之旅(十五)-动态事件处理方法 韩睿 "大李哥,"我不免为自己问了如此多的问题而不好意思起来,"您刚才所说的事件的委托是怎么回事呀?" 大李显然是明白我会提问的:"我所说过事件驱动设计中的三要素你还记得吧?" "当然,就是指对象.事件和事件处理程序."我流利地回答道. "对象和事件处理程序我们已经分析过了.要想彻底了解事件驱动程序的来龙去脉,我们必须了解事件的构成."见到我又一

Henry的VB.NET之旅(十一)—可视继承

继承 Henry的VB.NET之旅(十一)-可视继承 韩睿 闭关修练了一晚上VB.NET的继承程序的我,早上进入公司时自信满满.白经理看到我,问了一句:"学习得怎么样?对VB.NET是不是已经可以上手了?"我点了点头:"应该可以做点事了吧.""好的,"白经理拍了拍我肩膀说,"再跟大李好好学习几天,会有机会的." 得到领导的指示,我冲了杯咖啡,恭敬地走向大李,放在他的桌上.大李嘴角一翘,笑着说:"别这么客气,来,坐.让

Henry的VB.NET之旅(十三)—标准事件处理程序

标准|程序 Henry的VB.NET之旅(十三)-标准事件处理程序 韩睿 "感兴趣就好!"大李微微点点头,然后问我道,"你知道程序是怎么知道哪些对象可以引发何种事件,以及怎么样把事件和事件处理程序关联起来?" 见到我迷茫的眼神,大李用鼠标点击打开被Region合起来的"Windows 窗体设计器生成的代码",指着中间的一句自动生成的代码: Friend WithEvents Button1 As System.Windows.Forms.Butt

VB 从零开始编外挂(十二)

VB实现指针访问!DLL的访问 -------------------------------------------------------------------------------------------------------------------------------------------------------- CopyMemory函数提供了一个简单的方法来执行C++中见解访问运算符(*),这个运算符可以访问被一个指针变量所指向的变量的值.即如有指针变量 P,在C++中可

走近VB.Net(十二) 注册表快速入门

快速入门|注册表 走近VB.Net(十二) 注册表快速入门 作者:hejianzhong VB.Net中文站(http://vbnetcn.126.com) 首先介绍一下注册表的相关基础知识:注册表的每一个文件夹被称为一个Key(项),这个文件夹的子文件夹被称为SubKey(子项),而在一个子项中有不同的Value Name(值项-即数值顶),值项后面就是你要保存的数据Value Data(数据)了.而在子项中通常都有一个Default Value 是默认的Value Name,相信打开过注册表

Sql Server之旅——第十二站 sqltext的参数化处理

原文:Sql Server之旅--第十二站 sqltext的参数化处理   说到sql的参数化处理,我也是醉了,因为sql引擎真的是一个无比强大的系统,我们平时做系统的时候都会加上缓存,我想如果没有缓存,就不会有什么 大网站能跑的起来,而且大公司一般会在一个东西上做的比较用心,比较细,sqlserver同样也使用了缓存,其中就包括Data cache 和Plan cache两个大头. 现在我们也知道了Plan cache包括上一篇生成的xml结构和sql text,更有趣的是,sql text

JAVA之旅(二十四)——I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习

JAVA之旅(二十四)--I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习 JAVA之旅林林总总也是写了二十多篇了,我们今天终于是接触到了I/O了.如果你初学,不懂IO流,你可以从前往后慢慢看,但是你工作了一段时间你会发现,流的使用场景以及技术点是非常的强硬的,我们势必要掌握这个知识点,如果你觉得翻阅API比较鼓噪,看视频得不到精髓,看书看不到要点,你就跟随我的JAVA之旅,一起去探索吧! 一.I/O概述 I/O全名:Input Output

JAVA之旅(十二)——Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口

JAVA之旅(十二)--Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口 开始挑战一些难度了,线程和I/O方面的操作了,继续坚持 一.Thread 如何在自定义的代码中,自定义一个线程呢? 我们查看API文档,我们要启动一个线程,先实现一个子类, package com.lgl.hellojava; public class MyThread extends Thread { @Override public void run()