本演练演示如何为名为 Widget
的类声明和引发事件。 完成这些步骤后,可能需要阅读配套主题 “演练:处理事件”,该主题演示如何使用来自对象的事件 Widget
在应用程序中提供状态信息。
Widget 类
假设你目前有一个 Widget
类。 你的 Widget
类有一个方法可能需要很长时间才能执行,并且你希望应用程序能够设置某种类型的完成指示器。
当然,你可以让 Widget
对象显示一个完成百分比对话框,但是在你使用 Widget
类的每个项目中,你都会遇到该对话框。 对象设计的良好原则是让使用对象处理用户界面的应用程序,除非对象的全部用途是管理窗体或对话框。
添加 Widget
的目的是执行其他任务,因此最好添加一个 PercentDone
事件,让调用 Widget
方法的过程处理该事件并显示状态更新。 该 PercentDone
事件还可以提供取消任务的机制。
构建本主题的代码示例
打开一个新的 Visual Basic Windows 应用程序项目,并创建一个名为
Form1
的窗体。将两个按钮和一个标签添加到
Form1
。命名对象,如下表所示。
物体 资产 设置 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
事件由 LongTask
类的方法 Widget
引发。
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
类每秒引发一 PercentDone
次 MinimumInterval
事件。 当事件返回时, LongTask
检查参数是否 Cancel
设置为 True
。
此处需要一些免责声明。 为简单起见,该过程 LongTask
假定你事先知道任务需要多长时间。 这几乎从来就不是这样。 将任务划分为相等大小的块往往很困难,通常对用户而言,最重要的是他们在收到有事情在发生的迹象之前所经过的时间。
您可能已经注意到这个示例中的另一个缺陷。 该 Timer
属性返回自午夜以来传递的秒数;因此,如果应用程序在午夜前启动,应用程序将停滞。 更仔细地测量时间的方法会考虑边界条件,或者完全避免它们,使用诸如 Now
这样的属性。
现在,Widget
类可以引发事件,你可以转到下一个演练。
演练:处理事件 演示如何使用 WithEvents
将事件处理程序与 PercentDone
事件相关联。