VB 动态添加删除控件汇总

1.    概述  

在使用 Visual Basic  进行程序设计的过程中,如果能在运行时刻动态地创建和删除控件,可以极大地丰富界面的处理和变化。本人在设计网络监控系统时,需要在原理图与实物示意图间切换。切换的过程采用本文介绍控件的动态创建和删除来实现,有效地节省了系统资源,同时也有利于简化界面的维护。下面将就 Visual Basic 6.0 中的控件在运行时刻的创建和删除的两种方法——控件数组和控件集合作详细的阐述。

2.    基于控件数组的动态控件的创建与删除  

vb  中的控件数组实际上也是一种数组,其中的每个控件具有相同的 Name 属性,但具有不同的 Index 属性,在这里 Name 属性类似于数组的名字,而 Index 属性类似于数组的下标同时,控件数组也支持普通 VBA 数组的 LBound  、 UBound 和 Count 方法,控件数组中的控件可以共享一个事件过程,便于代码的编写和集中处理,这正是使用控件数组的最大的理由。

但是控件数组与普通的数组并非完全一样,它不需要定义大小,只有这样我们才可以动态的扩展[kuo zhan]它。

下面给出利用 Load 命令动态添加控件和 Unload 命令动态删除控件的一般方法:

(1)              首先在窗体上放置一个 TextBox ,其 Name 属性设置为 Text1 , Index 属性设置为 0 ,这样我们就创建了一个 TextBox 控件数组,其中有一个成员。

(2)              在窗体上放置一个命令按钮 Command1 ,在其 Click 事件中添加如下的代码:

Load Text1(1)

Text1(1).left=0

Text1(1).visible=true

(3)              在窗体上放置一个命令按钮 Command2 ,在其 Click 事件中添加如下的代码:

Unload Text1(1)

(4)              运行。单击命令按钮 Command1 ,窗体上会出现一个新的文本框;单击命令按钮 Command2 ,窗体上刚出现的新的文本框就被删除。

需要注意的是: Load 命令创建的控件 Text1(1) 与设计时已经放在窗体上的控件 Text1(0) 有完全相同的属性,也包括大小和位置等属性,例外的就是 Index 属性不一样, Visible 属性默认为 False, 所以必须在 Load 方法执行之后,执行调整控件位置的语句[yu ju],并把其 Visible 属性设置为 True ,以便在窗体上可见。 Unload 命令只能删除动态加载的控件,若删除设计时创建的控件会产生错误[cuo wu]。

另外,利用上面提到的数组的一些方法,可以有效的简化代码的编写。以下的代码可以删除所有动态创建的 Text1 控件数组中的控件 :  

Do While Text1.Count>1

Unload Text1(Text1.Ubound)

Loop

需要说明[shuo ming]的是,菜单数组是控件数组的一种特殊的形式,只是它是在菜单编辑器[bian ji qi]中设置相应的 Name 和 Index 属性,而且要求一个菜单控件数组中的菜单项必须是同一级菜单,但是不能创建新的顶级菜单。而动态创建和删除菜单项的方法也使用 Load 和 Unload 方法,只是默认情况下其 Visible 属性是 True, 而且不用重新设置相应的位置。    

3.    基于控件集合的动态控件的创建与删除  

VB  中提供一个 Controls 集合,用以包含当前窗体中的所有的控件,这对于实现一些功能相对复杂的操作相当有好处。而且 Controls 集合也是集合的一种,它支持一般集合的 Count 等方法和相应的检索[jian suo]机制[ji zhi]。以下两例就是利用这个控件集合的巧妙实现。

要清空当前窗体上的所有的文本框,可以如下实现:

Dim Ctl as Control

For Each Ctl in Controls

If Typeof Ctl is Textbox then

Ctl.Text=  ””

Endif

Next Ctl

也可以利用集合的 Count 方法如下实现:

For i=0 To    Controls.Count-1

If Typeof Ctl is TextBox

Controls(i).Text=  ””

Endif

Next i

当然,控件集合毕竟是一种特殊的集合,下面给出利用 Add 方法动态添加控件, Remove 方法动态删除控件的一般方法:

(1)              Controls  集合的 Add 方法

其语法[yu fa]格式为:

Set mycontrol = controld.Add(ProgId, Name, [Container])

在这里, mycontrol 是一个自定义的控件对象,若需要新创建的控件对事件做出反应,还要再定义该对象时增加 WithEvents 关键字

ProgId  是库名 . 控件名形式的控件类的名字, ToolBox  中的控件一般具有类似于 VB.CommandButton 这样的形式。而 Active X 控件的形式则有所差别,比如若使用 Windowless 控件库中的控件一般具有类似于 MsWless.WlText 的形式。

Name  参数是想赋给控件的名字,与控件的 Name 属性相对应。

Container  参数是可选的,它代表欲放置控件的容器,默认情况下是放置在窗体上。

下例是在窗体上动态创建一个命令按钮,然后单击命令按钮时,执行相应的动作:

Dim WithEvents mycontrol As CommandButton

Private Sub Form_Load()

Set mycontrol = Controls.Add("VB.commandbutton", "mycontrol")

mycontrol.Left = 0

mycontrol.Caption = "my"

mycontrol.Visible = True

End Sub



Private Sub mycontrol_click()

MsgBox "You click me!", vbExclamation

End Sub

需要注意,动态创建的控件必须指定相应的属性,而且在默认情况下,其 Visible 属性是 False 。

(2)              Controls  集合的 Remove 方法

利用 Controls 集合的 Remove 方法可以删除用 Add 方法动态创建的控件。其语法[yu fa]格式为:

Controls.Remove   “  控件名  ”

比如以上创建的 mycontrol 要删除可以使用如下的命令:

Controls.Remove "mycontrol"

同样应该注意,不能删除一个不存在或者在设计时创建的控件。

4. Active X    控件的动态创建和删除  

以上论述的方法适合于控件在应用程序[ying yong cheng xu]工具箱( TOOLBOX )中的情况,而  Active X  控件一般在应用程序[ying yong cheng xu]运行机器上,但没有在工具箱中,这种情况则需要先进行注册,方法是利用 Regsvr32 在 Windows 环境中注册,或者在 VB 代码中进行注册,方法如下:

Shell(Systempath   &   “  regsvr32.exe /s /I"   &  MyControlName, vbHide)   

其中 Systempath 是 Regsvr32.exe 所在的路径,  MyControlName 是控件名字(包括路径)

若要撤销,可以如下操作:

Shell(Systempath   &   “  regsvr32.exe /s /U"   &  MyControlName, vbHide)   

下面讨论注册但是未出现在工具箱( TOOLBOX )中的  Active X  控件的情况,这其中也包括 VB 自带的一些 Active X 控件的使用。具体的方法就是利用 VBControlExtender 对象。 VBControlExtender 对象与 EventInfo 相结合能提供事件陷井捕捉,它提供了一套通用的属性、方法、事件给开发人员,它的一个突出特点是能编程设计控件的事件,声明时若使用 WithEvents 关键字,则会有个特殊的事件 ObjectEvent(Info As EventInfo) ,它能捕捉到对象使用 RaiseEvent 产生的所有事件, EventInfo 数据结构[jie gou][shu ju jie gou]映射[ying she]了事件的名称、参数个数和参数的值。 VBControlExtender 和  EventInfo 相结合,采用 Select Case  就可以预先将不同类对象的事件放置一起,各自独立[du li]运作。

下面的例子是使用未在工具箱( TOOLBOX )中出现的 RichTextBox 的方法,其他的  Active X  控件的使用方法与此类似:

Dim WithEvents myControl As VBControlExtender

Private Sub Form_Load()

Licenses.Add "RichText.RichTextctrl.1"

Set myControl = Controls.Add("RichText.RichTextctrl.1", "mycontrol")

myControl.Left = 0

myControl.Visible = True

End Sub

Private Sub myControl_ObjectEvent(Info As EventInfo)

Select Case Info.Name

Case "MouseDown"

MsgBox "mousedown"

Case Else

‘  其他事件

End Select

End Sub

需要注意, Licenses.Add "RichText.RichTextctrl.1" 是响应[xiang ying]控件的对象编号在 VB 中的注册,若此控件已经出现在工具箱( TOOLBOX )中,则会出错。

另外,若 Active X 控件已经出现在 TOOLBOX 中,需要动态建立控件,则应该作如下的处理:首先去掉 Licenses.Add "RichText.RichTextctrl.1" 这一句,然后,在“工程属性窗口[chuang kou]”的“ Make ”页面下,确保[que bao]“ remove information about unused ActiveX controls ”不被选中即可。

还有,若 Active X 控件已经出现在 TOOLBOX 中,需要动态建立控件,还可以用类似于前面介绍的控件集合的方法,比如上面示范的 RichTextBox 的例子还可以如下实现(只是这种方法不再支持 ObjectEvent 事件):

Dim WithEvents myControl As RichTextLib.RichTextBox

Private Sub Form_Load()

Set myControl = Controls.Add("RichText.RichTextctrl.1", "mycontrol")

myControl.Left = 0

myControl.Visible = True

End Sub



Private Sub myControl_Click()

MsgBox "click"

End Sub

5 . 结束语  

通过以上对 Visual Basic 中的控件动态建立和删除进行了讨论,我们了解到控件数组  适  合于应用程序[ying yong cheng xu]中需要该控件,但需要控件实例的具体数量不定的情况;而控件集合则适合于为了完成不同的任务[ren wu],制作了多个不同功能的控件,在特定条件[tiao jian]下只需要一个或几个控件的情况对于 Active X 控件,若没有添加到 VB 工具箱中,当应用程序[ying yong cheng xu]执行时,可以根据需要由程序自动加载或者删除。总之,合理地选择[xuan ze]使用以上的各种方法,对于提高编程的效率和代码的运行效率都是大有裨益的。

以上有关的代码都已在 Windows 2000 Professional  和  Visual Basic 6.0  企业版环境下测试通过。


'//oooooooooooooooooooooooooooooooooooooooooooooooooooooo
' 以下是完整的测试代码--------------2011-1-21 BY ZHJ
'//oooooooooooooooooooooooooooooooooooooooooooooooooooooo
Option Explicit
Dim WithEvents mycontrol As CommandButton  '这句要放在全局定义
Dim x1, y1


Private Sub Command1_Click()
    If isControlExists("mycontrol") = True Then: Exit Sub
    Set mycontrol = Controls.Add("VB.commandButton", "mycontrol")
    With mycontrol
        .Caption = "可以拖动我看看!"
        .Left = 100
        .Width = 3000
        .Visible = True
    End With
End Sub

Private Sub Command2_Click()
    If isControlExists("mycontrol") = False Then: Exit Sub
    Controls.Remove "mycontrol"
End Sub

Private Sub Command3_Click()
    mycontrol_Click
End Sub

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Me.Caption = X & "," & Y
End Sub

Private Sub mycontrol_Click()
    Dim obj As Object
    Dim str
    For Each obj In Controls
        str = str & vbCrLf & obj.Name
    Next
    If isControlExists("mycontrol") = True Then
        MsgBox str, , "你点击了我!"
    Else
        MsgBox str, , "控件已删除!"
    End If
End Sub



'//自定义函数,判断控件是否存在
Function isControlExists(ctlName As String) As Boolean
    Dim obj As Object
    For Each obj In Controls
        If obj.Name = ctlName Then
            isControlExists = True
            Exit Function
        End If
    Next
    isControlExists = False
End Function

Private Sub mycontrol_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    'Me.Caption = X & "," & Y
    If x1 > 0 And y1 > 0 Then
        With mycontrol
            .Left = .Left + (X - x1)
            .Top = .Top + (Y - y1)
        End With
    End If
End Sub

Private Sub mycontrol_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    x1 = X: y1 = Y
End Sub

Private Sub mycontrol_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
    x1 = IIf(x1 > 0, 0, x1)
    y1 = IIf(y1 > 0, 0, y1)
End Sub

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页