演练:声明和引发事件 (Visual Basic)
本演练演示如何为名为 Widget
的类声明和引发事件。 完成这些步骤后,可能需要阅读配套主题演练:处理事件,该主题演示如何使用 Widget
对象中的事件在应用程序中提供状态信息。
Widget 类
假设你目前有一个 Widget
类。 Widget
类具有可能需要很长时间才能执行的方法,并且你希望应用程序能够设置某种完成指示器。
当然,你可以让 Widget
对象显示一个完成百分比对话框,但是在你使用 Widget
类的每个项目中,你都会遇到该对话框。 对象设计的一个良好原则是让使用对象的应用程序处理用户界面,除非该对象的整个用途是管理窗体或对话框。
Widget
的用途是执行其他任务,因此最好添加 PercentDone
事件,让调用 Widget
的方法的过程处理该事件并显示状态更新。 PercentDone
事件还可以提供取消任务的机制。
生成本主题的代码示例
打开新的 Visual Basic Windows 应用程序项目,并创建名为
Form1
的窗体。将两个按钮和一个标签添加到
Form1
。按下表所示命名对象。
Object 属性 设置 Button1
Text
启动任务 Button2
Text
取消 Label
(Name)
,Text
lblPercentDone、0 在“项目”菜单中,选择“添加类”以将名为
Widget.vb
的类添加到项目。
声明 Widget 类的事件
使用
Event
关键字在Widget
类中声明事件。 请注意,事件可以具有ByVal
和ByRef
自变量,如Widget
的PercentDone
事件所示:Public Event PercentDone(ByVal Percent As Single, ByRef Cancel As Boolean)
当调用对象收到 PercentDone
事件时,Percent
自变量包含已完成任务的百分比。 Cancel
自变量可以设置为 True
,以取消引发事件的方法。
注意
可以正如处理过程的自变量一样来声明事件自变量,不过有以下例外:事件不能具有 Optional
或 ParamArray
自变量,并且事件没有返回值。
PercentDone
事件由 Widget
类的 LongTask
方法引发。 LongTask
有两个自变量:方法假定正在工作的时间长度,以及 LongTask
暂停引发 PercentDone
事件之前的最小时间间隔。
引发 PercentDone 事件
若要简化对此类使用的
Timer
属性的访问,请将Imports
语句添加到类模块声明部分的顶部,在Class Widget
语句上方。Imports Microsoft.VisualBasic.DateAndTime
将以下代码添加到
Widget
类:Public Sub LongTask(ByVal Duration As Single, ByVal MinimumInterval As Single) Dim Threshold As Single Dim Start As Single Dim blnCancel As Boolean ' The Timer property of the DateAndTime object returns the seconds ' and milliseconds that have passed since midnight. Start = CSng(Timer) Threshold = MinimumInterval Do While CSng(Timer) < (Start + Duration) ' In a real application, some unit of work would ' be done here each time through the loop. If CSng(Timer) > (Start + Threshold) Then RaiseEvent PercentDone( Threshold / Duration, blnCancel) ' Check to see if the operation was canceled. If blnCancel Then Exit Sub Threshold = Threshold + MinimumInterval End If Loop End Sub
当应用程序调用 LongTask
方法时,Widget
类每 MinimumInterval
秒引发一次 PercentDone
事件。 当事件返回时,LongTask
检查 Cancel
自变量是否设置为 True
。
此处需要一些免责声明。 为简单起见,LongTask
过程假定你提前知道任务需要多久。 这种情况几乎永远不会发生。 将任务划分成大小均匀的区块可能很困难,通常,对于用户来说最重要的只是用户获得事件发生的指示之前所经过的时间。
你可能已发现此示例中的另一个缺陷。 Timer
属性返回自午夜以来经过的秒数;因此,如果应用程序在午夜之前启动,则应用程序会停滞。 测量时间更仔细的方法会考虑此类边界条件,或者使用 Now
等属性来完全避免这些条件。
现在,Widget
类可以引发事件,你可以转到下一个演练。 演练:处理事件演示如何使用 WithEvents
将事件处理程序与 PercentDone
事件相关联。