网摘》控件数组

控件数组(针对 Visual Basic 6.0 用户)

在 Visual Basic 6.0 中,控件数组可用于管理窗体上的控件;它们提供的功能可共享事件处理程序、循环访问控件组以及在运行时添加控件。

Visual Basic 2008 中不再支持控件数组。对事件模型的更改使控件数组不再必需,而且 .NET Framework 提供了相同的功能来处理控件。

共享事件处理程序

在 Visual Basic 6.0 中,控件数组可用于指定一组共享事件集的控件。这些控件应该为相同的类型,并且具有相同的名称。

Visual Basic 2008 允许使用任何事件处理程序处理来自多个控件的事件,甚至是具有不同名称和不同类型的控件。

例如,可以向窗体添加两个 Button 控件(Button1 和 Button2)以及一个 CheckBox 控件 (CheckBox1),然后创建一个事件处理程序来处理这三个控件的 Click 事件。

Private Sub MixedControls_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click, CheckBox1.Click

循环访问控件

Visual Basic 6.0 控件数组的另一个功能是使用 Index 属性循环访问控件组。例如,若要清除控件数组中所有 TextBox 控件的文本,可将 Index 属性作为循环变量循环访问控件数组。

Visual Basic 2008 控件没有 Index 属性,但仍可使用 Control 类的 Control.ControlCollection 循环访问窗体或容器上的控件。

在 Visual Basic 6.0 中,单个控件数组中的控件可位于不同容器上。例如,两个不同 Frame 控件上包含的 TextBox 控件可以是同一控件数组的元素。

在 Visual Basic 2008 中,Controls 集合仅返回位于同一容器上的控件。必须分别循环访问每个容器控件的控件;可使用递归函数完成此操作。

在运行时添加控件

在 Visual Basic 6.0 中,可使用 Load 语句在运行时向控件数组添加控件。控件必须和控件数组是同一类型,并且控件数组必须在设计时创建,且必须带有至少一个元素。添加控件后,必须将 Visible 属性设置为 True。

在 Visual Basic 2008 中,通过在 Dim 语句中使用 New 关键字,然后将 Add 方法用于要添加控件的容器,可在运行时添加控件。

在运行时添加事件处理程序

在 Visual Basic 6.0 中,在运行时向控件数组添加控件时,控件数组的事件自动处理新控件事件。

在 Visual Basic 2008 中,需要为运行时添加的控件定义事件处理程序。可使用 AddHandler 语句完成此操作。

控件数组的代码更改

下面的代码演示 Visual Basic 6.0 与 Visual Basic 2008 在编码方法方面的差异。

共享事件处理程序

下面的示例演示如何为一组三个 TextBox 控件共享 Change 事件处理程序(Visual Basic 2008 中为 TextChanged)。在 Visual Basic 2008 中,事件处理程序的 Handles 子句指定事件将处理的控件。事件处理程序返回一个泛型 Object,因此必须强制转换为要使用 Object 方法处理的特定对象类型(在本例中为 TextBox)。

' Visual Basic 6.0

Private Sub Text1_Change(Index As Integer)

Select Case Index

Case 0

MsgBox("The text in the first TextBox has changed")

Case 1

MsgBox("The text in the second TextBox has changed")

Case 2

MsgBox("The text in the third TextBox has changed")

End Select

End Sub

' Visual Basic

Private Sub TextBoxes_TextChanged(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles TextBox1.TextChanged, _

TextBox2.TextChanged, TextBox3.TextChanged

    Select Case DirectCast(sender, TextBox).Name

        Case TextBox1.Name

            MsgBox("The text in the first TextBox has changed")

        Case TextBox2.Name

            MsgBox("The text in the second TextBox has changed")

        Case TextBox3.Name

            MsgBox("The text in the third TextBox has changed")

    End Select

End Sub

【说明】事件行为在 Visual Basic 2008 中略有不同。初始化每个控件时(例如在 Form_Load 中)以及运行时更改文本时,引发 TextChanged 事件。在 Visual Basic 6.0 中,仅当文本发生更改时引发 Change 事件。

循环访问控件

下面的示例演示循环访问一组文本框控件并清除它们的文本的函数。在 Visual Basic 6.0 示例中,控件数组的 Index 属性用作循环变量。

在 Visual Basic 2008 中,Control 对象作为参数传递;它具有一个包括该控件上所有控件的 Control.ControlCollection 集合。Typeof 运算符用于确定每个控件是否是 TextBox 类型。

【说明】Form 对象是 Control 类型;也可将 Form 作为参数传递。

因为 Control.ControlCollection 集合中不包括嵌套控件,所以使用 HasChildren 方法确定每个控件是否包含其他控件,如果包含则递归调用 ClearText 函数。

' Visual Basic 6.0

Private Sub ClearText()

For i = 0 To Text1().UBound

Text1(i).Text = ""

Next

End Sub

' Visual Basic

Private Sub ClearText(ByVal container As Control)

    Dim ctrl As Control

    For Each ctrl In container.Controls

        If TypeOf (ctrl) Is TextBox Then

            ctrl.Text = ""

        End If

        If ctrl.HasChildren Then

             ClearText(ctrl)

        End If

    Next

End Sub

在运行时添加控件

下面的示例演示如何在运行时向窗体添加文本框控件。在 Visual Basic 6.0 中,控件添加到控件数组。在 Visual Basic 2008 中,该控件会添加到 Control.ControlCollection 集合。在 Visual Basic 6.0 中,新 TextBox 的事件由控件数组自动处理。在 Visual Basic 2008 中,需要通过 AddHandler 语句挂钩事件处理。

两个示例都假定文本框控件是在设计时添加到窗体中的,在 Visual Basic 6.0 示例中还假定创建了一个单元素控件数组。Visual Basic 2008 示例还假定对于第一个 TextBox 控件,存在名为 TextChangedHandler 的事件处理程序。

' Visual Basic 6.0

Private Sub AddControl()

' Add a TextBox as the second element of a control array.

Load Text1(1)

' Set the location below the first TextBox.

Text1(1).Move Text1(0).Left, Text1(0).Top + 500

' Make the new TextBox visible

Text1(1).Visible = True

' Visual Basic

' Declare a new TextBox.

Dim TextBox2 As New TextBox

' Set the location below the first TextBox

TextBox2.Left = TextBox1.Left

TextBox2.Top = TextBox1.Top + 30

' Add the TextBox to the form's Controls collection.

Me.Controls.Add(TextBox2)

AddHandler TextBox2.TextChanged, AddressOf TextChangedHandler

http://msdn.microsoft.com/zh-cn/library/kxt4418a(v=vs.90).aspx
 
 

控件数组正确使用方法分析

创建数据驱动窗体

所谓数据驱动窗体就是根据所请求的数据的不同生成相应的窗体。举例来讲,假设你现在有一个数据库,其中有些字段必须根据登录者的身份加以显示,授权级别高的用户可以浏览并修改这些字段的内容;授权级别一般的用户只能浏览这些字段中的数据;授权级别低的用户则不能浏览这些字段中的内容。要做到这一点就得利用VB动态添加控件的功能。

动态创建控件

无论你想要创建何种类型的数据驱动窗体,你必须知道如何在运行时动态地创建控件。你可以通过控件数组做到这一点,但 VB6的Controls集合所提供的Add方法,功能更强大,灵活性更高。使用该方法,你不需要在设计时将控件的实例放在窗体上。实际上,用Add方法 你甚至可以创建程序在编译时根本不存在的控件。这种方法的用法也很简单:

‘ 声明一个窗体级的变量

Dim WithEvents txtTotal As TextBox

 

Sub CreateTextbox()

‘ 创建新的Textbox控件

Set txtTotal = Controls.Add("VB.TextBox", "txtTotal")

‘ 将控件移动到你所需要的地方

txtTotal.Move 1000, 800, 1200, 300

‘ 创建时,所有的控件都是不可见的

txtTotal.Visible = True

End Sub

请注意Add方法的第二个参数:分配给控件的名称。从代码可读性出发,这个名称一般都与变量名相同。你可以用这个名称从Controls集合中获取相应的控件或移除该控件。例如:

Controls.Remove "txtTotal"

在变量声明时加上WithEvents关键字,即使在设计时窗体不存在该控件,你也可以为该控件的事件编写代码。

上面所讲的方法只适合解决VB内置的控件。例如,当你要添加一个TreeView控件时,VB会要求你证明你已经得到了合法的授权来创建该控件的实例。换句话说,VB要证明这个控件是买来的,而不是从其它附有该控件的程序中借来的。

要证明你经过了合法的授权有下面几种方法:

在窗体上放置一个控件。这也是最简单的方法。你完全没有必要将这个窗体显示出来。

将相关的控件添加到工具箱中,然后在“工程属性”对话框的“生成”标签页中取消选择“删除有关未使用的ActiveX控件的信息”这一项。

向Licenses集合添加一个元素。例如:Debug.Print Licenses.Add("MSMask.MaskedEdBox")

仅仅创建了控件并不足够

要创建一个数据驱动窗体,仅仅知道动态创建控件还不够。例如:现在你要创建一个能根据数据库中表的不同字段自动生成控件的窗体。该窗体可能会创建单行文本框,其长度随字段长度不同而不同;也可能会创建单选按钮或复选按钮以显示布尔型字段;甚至可能创建一个多行文本框显示备注型字段。

你需要解决的第一个问题是:文本框控件的Multiline属性在运行时是只读的,只在设计时可用。幸好,微软的Microsoft Windowless Controls 6.0可以解决这个问题。这组控件集包括了轻量级的TextBox,ComboBox,ListBox,CheckBox,OptionButton, CommandButton和两个scrollbar控件。这些控件与VB内置的相应的控件最大的区别在于:这些控件的所有属性在运行时是可读写的。在 VB的安装光盘中的Common\Tools\VB\WinLess文件夹中可以找到这个控件组。用下面的代码可以创建一个多行文本框:

 

Dim WithEvents txtEditor As MSWLess.WLText

 

Private Sub CreateEditor()

Set txtEditor = Controls.Add( "MSWLess.WLText", "txtEditor")

txtEditor.Move 0, 0, 4000, 4000

txtEditor.MultiLine = True

txtEditor.ScrollBars = wlBoth

txtEditor.Visible = True

End Sub

另外一个问题比较复杂:在事先不知道要创建多少个控件的情况下,如何给每个对新创建的控件的引用分配唯一的带WithEvents关键字的变量。换句话说就是要对新创建的控件的事件进行编程,前提是你在设计时不知道程序会创建多少个控件。使用对象数组显然不行,因为不能用WithEvents关键字声明一个对象数组;更坏的情况是,资一个变量定义为As Control或As Object也不行,因为还是不能用WithEvents。

问题源自于我们无法在运行时捕获一个对象数组事件。所以我们只能采取曲线救国的办法。所要的编写的代码可能比你想象的多,不过这个解决方法很有趣,值得我们这样去做。

我们需要两个辅助类模块来捕获事件,分别取名为ControlItems和ControlItem。ControlItems是一个集合类,其中保存了 ControlItem对象及其数量。该数量等于你所要对之编程的控件的数量。ControlItem类的每一份实例捕获控件产生的事件,然后调用在其所属的ControlItems集合类中的过程,最后由ControlItems在窗体中触发事件并执行事件中的代码。整个过程如下图所示:

捕获多个控件的事件

为简单起见,假设你要捕获来自所有的动态添加到窗体上去的控件的Validate事件。为完成这个工作,ControlItems集合类必须向父窗体展示该事件,并随时准备接收来自其子ControlItem类的通知以触发事件。代码如下:

 

Event Validate(CtrlItem As ControlItem, Cancel As Boolean)

Private m_ControlItems As New Collection

 

‘ 向集合中添加一个新的ControlItem项目

Function Add(ctrl As Control) As ControlItem

Dim newItem As New ControlItem

newItem.Init ctrl, Me

‘ 添加到私有类

m_ControlItems.Add newItem

‘ 返回新项目给调用者

Set Add = newItem

End Function

 

Friend Sub Notify_Validate(Item As ControlItem, Cancel As Boolean)

RaiseEvent Validate(Item, Cancel)

End Sub

ControlItem 类必须捕获来自动态添加到窗体中的控件的事件,并通知其所属的ControlItems集合类。很显然,ControlItem类必须有一个用 WithEvents关键字定义的变量来引用真正的控件。这意味着你不能将变量声明为As Control或As Object。如果你决定在窗体中所动态添加的控件不使用VB内置的控件的话,这个问题的解决办法相当的简单。你只需要将变量声明为 VBControlExtender类型就行了。对于创建数据驱动窗体来讲,不使用VB内置的控件并不是一件大不了的事。

将变量声明为 VBControlExtender,并加上WithEvents关键字,你就能直接捕获Validate,GotFocus,LostFocus, DragDrop和DragOver这几个事件了。如果要捕获其它更多的事件,你可以使用ObjectEvent。下面是ControlItem类模块中 的代码:

 

Public WithEvents Ctrl As VBControlExtender

‘ 所属的ControlItems对象

Dim m_Parent As ControlItems

 

Sub Init(ctl As Object, parnt As ControlItems)

Set Ctrl = ctl

Set m_Parent = parnt

End Sub

 

Private Sub Ctrl_Validate(Cancel As Boolean)

‘ 通知所属的ControlItems类

m_Parent.Notify_Validate Me, Cancel

End Sub

将下面的代码放入窗体中,就可以捕获动态添加的控件所产生的事件了:

 

Dim WithEvents CtrlItems As New ControlItems

 

Private Sub cmdCreateControls_Click()

Dim ctrl As Control

‘ 创建两个文本框并将它们添加到ControlItems集合? Set ctrl = Controls.Add("MSWLess.WLText", "One")

ctrl.Move 100, 200, 1000, 300

ctrl.Visible = True

CtrlItems.Add ctrl

‘ 注意你可以使用同一个变量

Set ctrl = Controls.Add("MSWLess.WLText", "Two")

ctrl.Move 100, 800, 1000, 300

ctrl.Visible = True

CtrlItems.Add ctrl

End Sub

 

Private Sub CtrlItems_Validate( CtrlItem As ControlItem, Cancel As Boolean)

‘ 拒绝空字符串 - 注意如何引用控件的属? If CtrlItem.Ctrl.Text = ""

Then Cancel=True

End Sub

 

现在解决了最困难的部分,要创建一个数据驱动窗体就变得简单了

****************************************************************

动态添加控件

VB6有一个新功能,可以动态添加控件,不用控件数组:

object.Add (ProgID, name, container)

参数说明

Object 必需的。一个对象表达式,其值是“应用于”列表中的一个对象。

ProgID 必需的。一个标识控件的字符串。大多数控件的 ProgID 都可通过查看对象浏览器来决定。控件的 ProgID 是由控件的库和类组成的。

例如,CommandButton 控件的 ProgID 是 VB.CommandButton。在ProgID 与对象浏览器中所显示的不一样的情况下,Visual Basic

将显示一个包括正确 ProgId 的错误信息。

name 必要的。一个字符串,用来标识集合的成员。

container 可选的。一个对象引用,它指定控件的容器。如果没有指定或为NULL,缺省值为 Controls 集合所属的容器。通过指定该参数,可以把一个控件放置在任何现存的容器控件(如 Frame 控件)中。用户控件或 ActiveX 文档也可以作为一个容器。

 

举例: //在picture1上面添加一个commandbutton

Private Sub Form_Load()

Form1.Controls.Add "VB.CommandButton", "cmdOk", Picture1

With Form1!cmdOk

.Visible = True

.Width = 500

.Caption = "确认(&Y)"

End With

End Sub

 

重点:当您添加一个未引用的需要许可证的控件到一个现存的(已部署好的)应用程序时,在使用 Add 方法之前您必须也添加这个控件的许可证关键字。

在运行时添加未引用的控件:

您也可以利用 Add 方法来动态添加一个在工程中没有被引用的控件。(“未引用的”控件是不出现在 Toolbox 中的控件)。为此,您必须也把控件的License 关键字添加到 Licenses 集合中。下面的示例中在添加控件本身之前添加了控件的许可证关键字:

Option Explicit

Private WithEvents extCtl As VBControlExtender

 

Private Sub Form_Load()

Licenses.Add "prjWeeks.WeeksCtl", "xydsfasfjewfe"

Set extCtl = Form1.Controls.Add("prjWeeks.WeeksCtl", "ctl1")

extCtl.Visible = True ‘ The control is invisible by default.

End Sub

 

但是,为了编程这样一个未引用控件的事件,您必须使用 WithEvents 关键字声明一个对象变量为VBControlExtender 对象(如上),并且设置该对象变量到Add 方法返回的引用上。然后,利用VBControlExtender 对象的 ObjectEvent事件来编程该控件的事件。下面是一个简单的例子。

 

Option Explicit

Dim WithEvents objExt As VBControlExtender ‘声明 Extender 变量

 

Private Sub LoadControl()

Licenses.Add "Project1.Control1", "xydsfasfjewfe"

Set objExt = Controls.Add("Project1.Control1", "myCtl")

objExt.Visible = True

End Sub

 

Private Sub extObj_ObjectEvent(Info As EventInfo)

‘使用 Select Case 编程控件的事件。

Select Case Info.Name

Case "Click"

‘这里处理 Click 事件。

‘现在显示其他的 case

Case Else ‘未知事件

‘这里处理未知事件。

End Select

End Sub

Note: 不能把一个固有的控件指定给这个 VBControlExtender 变量; 任何这种试图将引起类型不匹配错误。

但是,您也可以通过使用 WithEvents 关键字声明一个对象变量,并且设置该方法返回的引用为该变量,从而编程一个动态添加控件的事件,如下所示。

Option Explicit

‘声明对象变量为 CommandButton 。

Private WithEvents cmdObject As CommandButton

 

Private Sub Form_Load()

Set cmdObject = Form1.Controls.Add("VB.CommandButton", "cmdOne")

cmdObject.Visible = True

cmdObject.Caption = "Dynamic CommandButton"

End Sub

 

Private Sub cmdObject_Click()

Print "This is a dynamically added control"

End Sub

如果希望添加一个用户控件或任何 ActiveX 控件到您的窗体,必须或者把这个控件添加到“工具箱”,或者把控件的 License 关键字添加到 Licenses集合中。有关详细信息请参阅“增加方法 (Licenses 集合)”。

注意:如果您添加一个 ActiveX 或用户控件到您的工程,但是没有在窗体中使用它,您也必须不要选定“工程属性”对话框的“生成” 选项卡上的“删除有关未使用的 ActiveX 控件”选项。如果您的应用程序试图添加该控件,那么该 Add 方法将失败,因为必需的信息已经被丢弃。

http://blog.csdn.net/yuan_haijiang/article/details/7392468

 

 

 

VB控件数组的操作技巧(混合文本)

控件数组有在设计时设置好的,也有在运行中创建的。控件数组一方面使得程序简洁、令代码易于维护,另一方面能使程序具有灵活性。可见,科学地利用控件数组可使编程工作的效率更高。本文是从笔者回答网友的问题中整理出来的,与原来的回答相比略有改动。希望这些"技巧"对大家有些帮助。如有不妥之处,敬请指教。

一、运行中设置数组控件的属性

设窗体上有若干个以 Command1 命名的命令按钮,现要求:点击其中一个按钮后,该按钮不可用,而其它的按钮均可用。以下几行代码可以实现这个要求,比一个一个的设置高效得多。

Private Sub Command1_Click(Index As Integer)
    
Dim As Integer '计数器
    
Dim comNum As Integer '按钮的索引号
    
comNum 0
    
For To Command1.Count 1
        comNum 
comNum 1
        
If comNum Command1.Count Then comNum 0
        Command1
(comNum).Enabled True '让所有按钮可用
    
Next
    
Command1(Index).Enabled False '让被单击按钮不可用
End Sub

二、运行中添加和卸载数组控件

窗体上已有一个文本框Text1,程序需要在运行时动态地创建若干文本框,可这样实现:

1.首先,设计时给Text1的Index属性设置为"0",这一步很重要:有了索引号才能创建数组控件;

2.编写代码:[之前请给工程添加两个命令按钮,Name属性取缺省值,Caption属性分别为:添加、卸载]

Private Sub Command1_Click()
    Dim txtNum As Integer 'Text1
Index
    Dim Num As Integer '
赋给各TextBox的值
    txtNum = 0 '
初值
    Num = 1 '
初值
    Text1(0).Text = "Text" & Num '
第一个Text1的值
    Dim i As Integer '
计数器
    For i = 0 To 4 '
添加五个TextBox
        txtNum = txtNum + 1
        Num = Num + 1
        Load Text1(txtNum) '
加载文本框
        Text1(txtNum).Top = Text1(txtNum - 1).Top + 450 '
设置位置
        Text1(txtNum).Text = "Text" & Num '
加载内容
        Text1(txtNum).Visible = True '
令其可见:不能漏
    Next
    Command1.Enabled = False
    Command2.Enabled = True
End Sub

 

Private Sub Command2_Click()
    Dim i As Integer, N As Integer
    N = 0
    For i = 1 To Text1.Count - 1
        N = N + 1
        Unload Text1(N)
    Next
    Command1.Enabled = True
    Command2.Enabled = False
End Sub

三、给运行中添加的数组控件命名并编写事件

其实例二已经给数组控件命了名,只是简单了些。本例将文件夹"F:\Txt"下的所有.txt的文件名作为菜单的Caption添加到菜单项里[请事先建立此文件夹并拷贝一些.txt文件,或者更改代码],当点击这些菜单,程序将调出Windows的记事本打开相应的文件。

键入以下代码前请启动VB的菜单编辑器,建立一个父菜单项[Naem和Caption属性任意],然后在此父菜单下建立一个子菜单,Name属性为"mnuFiles",Caption属性为"没有文件"。

Dim MyPath As String '路径名变量
'
添加并命名菜单过程
Private Sub AddMenu()
    Dim MenuNum As Integer '
菜单索引号变量
    Dim MyFiles As String '
文件名变量
    MenuNum = 0 '
初值
    MyFiles = Dir(MyPath + "*.txt") '
仅查找文本文档
    If MyFiles = "" Then Exit Sub '
为空则退出过程
    mnuFiles(0).Caption = MyFiles '
给第一个菜单命名
    Do Until MyFiles = ""
        MyFiles = Dir()
        If MenuNum = 0 Then MenuNum = 1
        MenuNum = MenuNum + 1
        Load mnuFiles(MenuNum) '
加载菜单
        mnuFiles(MenuNum).Visible = True '
设置为可见:不能漏
        mnuFiles(MenuNum).Caption = MyFiles
        If mnuFiles(MenuNum).Caption = "" Then Unload mnuFiles(MenuNum)
        '
若菜单名为空则卸载掉
    Loop
End Sub

Private Sub Form_Load()
    MyPath = "F:\Txt\" '
规定路径
    Call AddMenu '
执行添加菜单过程
End Sub
Private Sub mnuFiles_Click(Index As Integer)
    Dim ret As String
    '
Windows的记事本打开文件:注意中间的空格不能少
    ret = "Notepad.exe" & " " & MyPath & mnuFiles(Index).Caption
    Shell ret, vbNormalFocus
End Sub

四、控件在窗体上的排列问题

曾有一位网友两次问土人怎样才能在窗体上添加100万个文本框。呵呵,这要多大的显示器才能显示出来呀!不过,添加的数组控件多了,排列确实是个问题。下面的例子给窗体添加499个Label控件,连同事先绘制好的Index号定义为0的控件,总共有500个,能在窗体上从左到右、从上到下整齐地排列。程序运行时要花些许时间。

Option Explicit
Private Sub Form_Load()
    Me.Width = 6800
    Me.Height = 6000
    Me.Caption = "
添加标签演示"
    With Label1(0)
        .Top = 0
        .Left = 120
        .Height = 200
        .Width = 300
        .Caption = ""
    End With
    AddLabels
End Sub
Private Sub AddLabels()
    Dim i As Integer '
计数器
    Dim Num As Integer 'Label
Index
    Dim k As Integer '
判断是否满行
    Dim n As Integer '
行数计数器
    Num = 0
    k = 0
    n = 0
    Label1(0).Caption = Num + 1
    For i = 1 To 499
        Num = Num + 1
        Load Label1(Num) '
加载Label控件
        Select Case k
            Case 0
                Label1(Num).Left = Label1(Num - 1).Left + Label1(0).Width + 20
                If Num = 20 Then n = n + 1: k = n
            Case n
                Label1(n * 20).Left = 120
                Label1(n * 20).Top = Label1(0).Height * n
                Label1(Num).Top = Label1(0).Height * n
                Label1(Num).Left = Label1(Num - 1).Left + Label1(0).Width + 20
                If Num = (n + 1) * 20 Then n = n + 1: k = n
        End Select
        Label1(Num).Caption = Num + 1
        Label1(Num).Visible = True
    Next
End Sub

一个问题的实例

回答人的补充

后面那代码,是告诉你什么情况用Select Case。

那就不能这样做了,2个的index是不同的,改为:

 

Private Sub Command1_Click()
    Dim i, r, s As Integer
    Dim p As Long
    For i = 0 To 2
        If Option1(i).Value Then
            Select Case i
                Case 0: s = 100
                Case 1: s = 120
                Case 2: s = 160
            End Select
        End If
    Next
    For i = 0 To 3
        If Option2(i).Value Then
            Select Case i
                Case 0: r = 3000
                Case 1: r = 3000 * 1.1
                Case 2: r = 3000 * 1.2
                Case 2: r = 3000 * 1.3
            End Select
        End If
    Next
    p = r * s
    Label1.Caption = "
根据所选房价应为:¥" & p
End Sub

 

1.将多个控件取相同的名称

具体操作步骤是:

1)绘制或选择要作为一个控件数组的所有控件,必须保证它们为同一类型的控件。

2)决定哪一个控件作为数组中的第一个元素,选定该控件并将其Name属性值设置成数组名(或使用其原有的Name属性值)。

3)将其他控件的Name属性值改成同一个名称。这时,Visual Basic会显示一个对话框,要求确认是否要创建控件数组,选择“是”则将控件添加到控件数组中。

例如,若原有三个文本框Text1、Text2、Text3,要将它们设置成控件数组,数组名称为TT,则选择第一个文本框Text1,将其Name属性修改成TT,然后再选择Text2,再将其Name属性改成TT,这时会出现下图所示的对话框,单击“是(Y)” 按钮将Text2添加到控件数组中。在属性窗口中可以看出原Text1和Text2文本框的名称都变成了TT。同样将Text3的名称也改成TT,这时不再出现提示对话框,而直接将Text3的名称改成TT。观察各控件的属性窗口中的Index属性,其值分别变成了0、1、2(即控件数组元素的索引)。

 

图 通过修改控件名称建立控件数组

用这种方法建立的控件数组元素仅仅具有相同的Name属性和控件类型,其他属性与最初绘制控件时的值相同。

 

2.复制现有的控件,并将其粘贴到所在容器中

具体操作步骤是:

1)在容器(如窗体)中绘制或选择要作为控件数组的第一个控件。

2)选择“编辑”菜单中的“复制”命令(或单击标准工具栏的“复制”按钮),然后选中容器,再在“编辑”菜单中选择“粘贴”命令(或单击标准工具栏的“粘贴”按钮)。Visual Basic同样会显示与上图类似的对话框,单击“是(Y)”按钮,确定要创建一个控件数组。

这时,绘制的第一个控件具有索引值0,而新粘贴的控件的索引值为1。以后可以继续使用粘贴的方法向现有的数组中添加控件,只是不再出现提示对话框,直接将新粘贴的控件作为控件数组的下一个元素。每个新数组元素的索引值与其添加到控件数组中的次序相同。用这种方法添加控件时,大多数可视属性,例如高度、宽度和颜色,将从数组中第一个控件复制到新控件中。

 

3.给控件设置一个Index属性值

具体操作步骤是:

1)绘制或选择要作为控件数组的第一个控件。

2)在属性窗口中直接指定一个Index属性值(如设置为0)。

3)使用以上两种方法之一添加数组中的其他控件,这时不再出现提示对话框询问是否要创建控件数组。

建立了控件数组之后,可以通过修改Index属性值修改相应控件在数组中的位置。当然,必须保证同一个控件数组中的各元素的Index属性值是惟一的。

Visual Basic控件数组的使用示例 - - - 同时移动一组图形

【例】创建图形控件数组S1,包含6个圆,当按下“移动”按钮时,所有圆全部向下移动100缇,当移动到窗体底部时,返回窗体顶部。界面如下图所示。

 

图 同时移动一组图形

分析:移动操作在单击“移动”按钮(设名称为Command1)时进行,因此,代码应写在“移动”按钮的Click事件过程中。这里要特别注意的是,“移动”按钮不是控件数组元素,因此,其事件过程不会返回Index参数值,也就是在其事件过程中不可以使用Index参数,这里可以用循环变量控制控件数组的索引,通过循环逐个移动图形。

“移动”按钮的Click事件过程如下:

 

Private Sub Command1_Click()
    For I = 0 To 5
        If S1(I).Top + S1(I).Height > Form1.ScaleHeight Then
            ' 
当图形底部超过窗体底部时,将图形移回窗体顶部
            S1(I).Top = 0
        Else
            ' 
当图形底部未超过窗体底部时,将图形向下移动100
            S1(I).Top = S1(I).Top + 100
        End If
    Next I
End Sub

 

对于不关心处理次序的控件数组,也可以使用For Each...Next循环进行处理,例如,上例移动图形无先后次序问题,程序可以改写成:

 

Private Sub Command1_Click()
    For Each X In S1
        If X.Top + X.Height > Form1.ScaleHeight Then
            X.Top = 0
        Else
            X.Top = X.Top + 100
        End If
    Next X
End Sub

 

 

 

 

各位大神,感谢前几次的帮助,另有一个问题
图1图2
如图所示,现在有opt1(i)  20个数组控件,正常情况下20个控件都是可以编辑的(opt1(i).Enabled=true),20个控件相连返回结果为true,如图1所示      如果因为其它原因导至其中一个或者多个不可编(opt1(i).Enabled=false),造成数组不相连,这样如何来检测这些数组中有哪些为不可编辑的,并在弹出的Msgbox中指出不可编辑的地方,如图2所示

 

楼主看看这个:

Option Explicit

 

Private Function CheckOpt(ByRef strRetVal As String) As Boolean

   Dim strTemp As String

   Dim i&, c&

   strTemp = String(60, "-")

   c = 0

   For i = opt1.LBound To opt1.UBound

      If (opt1(i).Enabled) Then

         c = c + 1

      Else

         Mid$(strTemp, i * 3 + 1, 2) = opt1(i).Caption

      End If

   Next

   i = opt1.Count

   If (i > c) Then

      strTemp = Replace(strTemp, "-2", " 2")

      strTemp = Replace(Replace(strTemp, "-1", " 1"), "-0", " 0")

      strRetVal = Replace(strTemp, "-", "")

   End If

   CheckOpt = i = c

End Function

 

' 调用示例

Private Sub Command1_Click()

   Dim strMSG As String

   If (CheckOpt(strMSG)) Then

      MsgBox "全部可编辑!", 64

   Else

      MsgBox "以下不可编辑:" & strMSG, 48

   End If

End Sub

 

If (i > c) Then  ...... End if 那段可以这样改下:

If (i = c) Then
   strRetVal = ""
Else
   strTemp = Replace(strTemp, "-2", " 2")
   strTemp = Replace(Replace(strTemp, "-1", " 1"), "-0", " 0")
   strRetVal = Replace(strTemp, "-", "")
End If

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值