通过限制焦点验证控件数据
Validate 事件和 CausesValidation 属性是在允许用户将焦点移开控件之前,串联使用以确认对控件的输入的。例如:假设有几个文本框和一个 Help 按钮的应用程序,当每个文本框接收焦点时,您想在文本框的特殊验证准则被满足之前阻止用户移动焦点;然而,您也想允许用户在任何时候都能单击 Help 按钮。 要做到这点,在 Validate 事件中设置验证准则,并将 Help按钮的 CausesValidation 属性设置为 False。假如属性设置为 True (缺省设置),Validate 事件将在第一个控件上发生。假如属性设置为 False,在第一个控件上的 Validate 事件将抢先发生。 Validate 事件比 LostFocus 事件更适合验证数据输入项,因为 LostFocus 事件(按照定义)是在焦点已移动后发生。相反,通过使用Validate 事件,您能防止焦点移动到另一个控件直到验证规则被满足。 可能的使用 数据输入项应用程序需要执行比 Masked Edit 控件所提供的或在业务规则中发生的有效性验证更复杂的数据输入项有效性验证。 窗体需要防止用户使用 TAB 键或加速键将控件移走,直到数据已被输入到字段中。 在 Internet Explorer 中运行的 ActiveX 文档需要一种方法,使用户在脚本程序化地移动焦点之前完成在窗体上的操作。
在 Validate 事件上控制焦点 Validate 事件包括一个 keepfocus 参数。当参数设置为 True时,控件将保留焦点。这样做有效地防止了用户单击其它控件。
使用控件数组 控件数组是一组具有共同名称和类型的控件。它们的事件过程也相同。一个控件数组至少应有一个元素,元素数目可在系统资源和内存允许的范围内增加;数组的大小也取决于每个控件所需的内存和 Windows 资源。在控件数组中可用到的最大索引值为 32767。同一控件数组中的元素有自己的属性设置值。常见的控件数组的用处包括实现菜单控件和选项按钮分组。 注意 Visual Basic 包括了在运行时动态地将未引用的控件添加到 Controls集合中的能力。本主题仅指在设计时通过将一个控件剪切和粘贴到窗体上添加的引用控件。有关在运行时添加控件的详细信息,请参阅参考主题“Add 方法(Controls 集合)”和“Add 方法(Licenses 集合)”。
为何使用控件数组 在设计时,使用控件数组添加控件所消耗的资源比直接向窗体添加多个相同类型的控件消耗的资源要少。当希望若干控件共享代码时,控件数组也很有用。例如,如果创建了一个包含三个选项按钮的控件数组,则无论单击哪个按钮时都将执行相同的代码。 若要在运行时创建一个控件的新实例,则新控件必须是控件数组的成员。使用控件数组时,每个新成员继承数组的公共事件过程。 使用控件数组机制是不可能在运行时创建新控件的,因为每个新控件都继承为数组编写好的事件过程。例如,如果窗体上有若干文本框,而且每个文本框都接受一个日期数值,则可创建一个控件数组,使所有文本框共享同一个合法性检查代码。
示例应用程序:Calc.vbp 图 7.2 所示的 Calculator 示例应用程序(列在 Samples!Alink("vbsamples")目录中)包含两个控件数组——数字按钮和操作按钮。
请注意示例是如何使用 object(index) 语法引用每个控件的。在创建控件时指定索引值。实际上,在设计时为一个控件指定任意的索引,这将使控件成为数组的一部分。 Index 属性区分控件数组中的元素。当数组中的一个控件识别了一个事件时,Visual Basic 将调用公共事件过程并传递一个参数(Index 属性的值),分辨是哪个控件识别事件。 例如,Number_Click 事件过程的第一行代码是这样的: Private Sub Number_Click (Index As Integer) 如果 Number(0) 识别事件,则 Visual Basic 将 0 作为 index 参数传递,而如果 Number(1) 识别事件,则 Visual Basic 将 1 作为 index 参数传递。与索引值不同,对于 Number(0) 到 Number(9) 已执行的其余 Number_Click代码都是相同的。
设计时创建控件数组 设计时有三种方法创建控件数组: 1.将相同名字赋予多个控件。 2.复制现有的控件并将其粘贴到窗体上。 3.将控件的 Index 属性设置为非 Null 数值。 注意 必须在“菜单编辑器”中创建菜单控件数组。关于此项操作的详细信息,请参阅第六章,“创建用户界面”中的“运行时创建和修改菜单”。 要通过改变控件名称添加控件数组元素: 1. 绘制控件数组中要添加的控件(必须为同一类型的控件)决定哪一个控件作为数组中的第一个元素。 2. 选定控件并将其 Name 设置值变成数组第一个元素的 Name 设置值。 3. 在数组中为控件输入现有名称时,Visual Basic 将显示一个对话框,要求确认是否要创建控件数组。此时选择“确定”确认操作。 例如,若控件数组第一个元素名为 cmdCtlArr,则选择一个 CommandButton将其添加到数组中,并将其名称设置为 cmdCtlArr,此时将显示这样一段信息:“已经存在名为 'cmdCtlArr' 的控件。是否要创建控件数组?”。选择“确定”确认操作。 用这种方法添加的控件仅仅共享 Name 属性和控件类型;其它属性与最初绘制控件时的值相同。 要通过复制现存控件添加控件数组元素: 1. 绘制控件数组中的控件。 2. 当控件获得焦点时,选择“编辑”菜单中的“复制”命令。 3. 在“编辑”菜单中,选择“粘贴”命令。Visual Basic 将显示一个对话框询问是否确认创建控件数组。选择“确定”确认操作。指定给控件的索引值为 1。绘制的第一个控件具有索引值 0。 每个新数组元素的索引值与其添加到控件数组中的次序相同。这样添加控件时,大多数可视属性,例如高度、宽度和颜色,将从数组中第一个控件复制到新控件中。 #p#分页标题#e# 运行时添加控件数组 在运行时,可用 Load 和 Unload 语句添加和删除控件数组中的控件,然而,添加的控件必须是现有控件数组的元素。必须在设计时创建一个(在大多数情况下)Index 属性为 0 的控件,然后在运行时使用如下语法: 加载控件数组的新元素时,大多数属性设置值将由数组中具有最小下标的现有元素复制——本例中是索引值为 0 的元素。因为不会自动把 Visible、Index 和 TabIndex 属性设置值复制到控件数组的新元素中,所以,为了使新添加的控件可见,必须将其 Visible 属性设置为 True。 注意 试图对数组中已存在的索引值使用 Load 语句时,Visual Basic 将生成一个错误。 重点 可用 Unload 语句删除所有由 Load 语句创建的控件,然而,Unload无法删除设计时创建的控件,无论它们是否是控件数组的一部分。
控件方案:在控件数组中添加和删除控件 如何在运行时添加和删除控件,控件数组示例对此作了演示,这里,控件是选项按钮。根据这个示例,用户可以添加选项按钮,改变图片框背景颜色。 如图7.3 所示,启动窗体,然后在上面绘制一个图片框、一个标签、两个选项按钮和三个命令按钮。 控件数组应用程序的事件 接着,必须添加选项按钮和命令按钮的事件过程。添加窗体声明后启动应用程序: Dim MaxId As Integer 所有选项按钮共享 Click 事件过程: Private Sub optButton_Click (Index As Integer) picDisplay.BackColor = QBColor(Index + 1) End Sub 通过“添加”命令按钮的 Click 事件过程添加新的选项按钮。本例中,在执行 Load 语句前,代码将检查确认加载的选项按钮数不超过十个。加载控件之后,必须将其 Visible 属性设置为 True。 Private Sub cmdAdd_Click () If MaxId = 0 Then MaxId = 1'设置全部选项按钮。 If MaxId > 8 Then Exit Sub '只允许十个按钮。 MaxId = MaxId + 1'按钮计数递增。 Load optButton(MaxId)'创建新按钮。 optButton(0).SetFocus '重置按钮选项。 '将新按钮放置在上一个按钮下方。 optButton(MaxId).Top = optButton(MaxId - 1)._ Top + 400 optButton(MaxId).Visible = True'显示新按钮。 optButton(MaxId).Caption = "Option" & MaxId + 1 End Sub 通过“删除”命令按钮的 Click 事件过程删除选项按钮: Private Sub cmdDelete_Click () If MaxId <= 1 Then Exit Sub'保留最初的两个按钮。 Unload optButton(MaxId)'删除最后的按钮。 MaxId = MaxId - 1'按钮计数递减。 optButton(0).SetFocus'重置按钮选项。 End Sub 通过“关闭”按钮的 Click 事件过程结束应用程序: Private Sub cmdClose_Click () Unload Me End Sub
|