1、VB如何用代码动态的创建控件数组?
前提是窗体上没有这个控件,要新生成一个。
比如窗体上只有一个按钮,其它什么都没有(不是隐匿了),我要每按一下按钮,就生成一个名为texttem的文本框,只是它们的index值不同。
2、有没有办法把在窗体上的线控件(line),移动到窗体上的某个容器当中(比如:picturebox,frame等),并让其显示!

解决方案 »

  1.   

    可以使用,用Controls.Add,如:
    Option Explicit
      
    Dim Text() As ObjectPrivate Sub Form_Load()
        Dim i As Integer
        Dim nTop As Long
        
        ReDim Text(1 To 10)
        For i = 1 To 10
            Set Text(i) = Controls.Add("VB.TextBox", "Text1" & CStr(i))
            Text(i).Height = 300
            Text(i).Top = nTop
            Text(i).Visible = True
            nTop = nTop + 30 * 15
        Next iEnd Sub与VB本身的控件数组区别在于,数组下标只能为1。
      

  2.   

    Option Explicit
      
    Dim Text() As ObjectPrivate Sub Form_Load()
        Dim i As Integer
        Dim nTop As Long
        
        ReDim Text(1 To 10)
        For i = 1 To 10
            Set Text(i) = Controls.Add("VB.TextBox", "Text1" & CStr(i))
            Text(i).Height = 300
            Text(i).Top = nTop
            Text(i).Visible = True
            nTop = nTop + 30 * 15
        Next iEnd SubPrivate Sub Form_Unload(Cancel As Integer)
        Dim i As Integer
        
        For i = 10 To 1
            Controls.Remove "VB.TextBox", "Text1" & CStr(i)
        Next
    End Sub
    别忘了删除控件。
      

  3.   

    上面代码有误,正确的如下:
    Option Explicit
      
    Dim Text() As ObjectPrivate Sub Command1_Click() '改变线控件的容器
        Set Me.Line1.Container = Me.Picture1
    End SubPrivate Sub Form_Load()
        Dim i As Integer
        Dim nTop As Long
        
        ReDim Text(1 To 10)
        For i = 1 To 10
            Set Text(i) = Controls.Add("VB.TextBox", "Text1" & CStr(i))
            Text(i).Height = 300
            Text(i).Top = nTop
            Text(i).Visible = True
            nTop = nTop + 30 * 15
        Next iEnd SubPrivate Sub Form_Unload(Cancel As Integer)
        Dim i As Integer
        
        For i = 10 To 1 Step -1
            Controls.Remove Text(i)
        Next
    End Sub
      

  4.   

    Private Sub Command2_Click()
    MsgBox Text(2).Index
    End Sub
    '返回-----对象不是数组
      

  5.   

    是的,是我手误,习惯性地写成了redim xx(1 to yy),所以在set xx(0)时出错,还以为是数组不能为0呢,误导了大家,对不起!
      

  6.   

    Private Sub Form_Load()
        Dim i As Integer
        Dim nTop As Long
        
        ReDim Text(1 To 10)
        For i = 1 To 10
            Set Text(i) = Controls.Add("VB.TextBox", "Text" & CStr(i))
            Text(i).Height = 300
            Text(i).Top = nTop
            Text(i).Visible = True
            Text(i).Text = Text(i).Name
            nTop = nTop + 30 * 15
        Next iEnd Sub
    这段代码所生成的动态控件不是数组,因为它们的名字不一样,它的功能和下面的代码的功能是一样的!
    Private Sub Form_Load()
        Dim i As Integer
        Dim nTop As Long
        Dim Text As TextBox
        For i = 1 To 10
            Set Text = Controls.Add("VB.TextBox", "Text" & CStr(i))
            With Text
                   .Height = 300
                   .Top = nTop
                   .Visible = True
                   .Text = Text.Name
                   nTop = nTop + 30 * 15
             End With 
        Next iEnd Sub
      

  7.   

    如果是添加单个控件而不是控件数组,用控件事件比较简单,
    dim withevents Text as textbox
    ..
    太简单了,不说了
    对控件数组,比较麻烦一些
    'Form
    Option ExplicitDim Text() As Object
    Dim clsT() As New Class1
    Private Sub Form_Load()
        Dim i As Integer
        Dim nTop As Long
        
        ReDim Text(10)
        ReDim clsT(10)
        For i = 0 To 10
            Set Text(i) = Controls.Add("VB.TextBox", "Text1" & CStr(i))
            Text(i).Height = 300
            Text(i).Top = nTop
            Text(i).Visible = True
            nTop = nTop + 30 * 15
            clsT(i).Init Text(i)    Next iEnd Sub
    'Class
    Option ExplicitDim WithEvents T As TextBox
    Private Sub T_Change()
    MsgBox 11
    End SubPublic Sub Init(tmp As TextBox)
    Set T = tmp
    End Sub
      

  8.   

    2、有没有办法把在窗体上的线控件(line),移动到窗体上的某个容器当中(比如:picturebox,frame等),并让其显示!
    设置line控件的parent属性为picturebox试试
      

  9.   

    第2个问题已经解决,4楼的朋友已经给出答案!我试过了,这个好使!
    Set Me.Line1.Container = Me.Picture1 
    但第一个问题4楼的朋友好像给出的不对吧!不是控件数组!因为不能用索引,我的目的就是想用索引!
      

  10.   

    由于VB的控件数组是通过前期绑定实现的,而Controls.Add只能实现后期绑定,故用这种办法不能实现,而LZ又排除了放置隐藏控件数组,然后用Load放置的方式,故实现起来相当困难。要自己从头编写一个类进行封装,我一会试验一下,成功了再告诉你。
      

  11.   

    太麻烦了,不是一般的麻烦,首先要自己用API实现一个TextBox类,还要实现Controls类,还要处理消息循环,得不偿失,建议LZ采取Load方式吧。
      

  12.   

    18楼的朋友,谢谢你的解答,现在我手头有一个工程,要根据收到的数据包,取出温度的值,之后画出曲线,在一个窗体上显示出来,温度取值我已经实现,问题是要在另一个窗体上实现实时的曲线显示,如果我只监控一个数据包,我可以实现曲线,用LOAD的方法把LINE的数组一个接一个的显示出来,可我要监控的是多个机器的数据包,并在一个窗体上显示,还要都是实时的,所以想只有控件数组可以实现,所以就上来问一问,如果这样不行的话,你有什么好方法可以实现这个功能吗?给个思路也行!谢谢!
      

  13.   

    晕啊那你干嘛不直接用Line方法来画线呢?怎么会想到用控件模拟!
      

  14.   

    如果用LINE的方法来画的话,要如何知道第几台机器的最后一个点的坐标?
    我的思路是,在窗体上加入一个PICTUREBOX这个控件,命名为PICOUT,在PICOUT这个控件里再画一个PICTUREBOX控件(为了实现边界滚动条)。在程序运行的时候从数据库当中读取数据,按数据动态生成FRAME这个控件(有几条数据,就生成几个,要在这里作动态的实时曲线的!其FRAME的CAPTION为各个机器的名字!NAME=FAMQX & adcqx.recordset.fiels(0),数据库控件为ADODC控件,名为adcqx,读取数据库中的字段0,是主关键字。),之后要在各个FRAME上画出坐标系,到这为止,我都会,并且都是用from.Controls.Add()这个方法加入的,就是到读入实时温度的时候,不知道要怎么在各个坐标系上画出曲线!我是想根据IP地址,在数据库中可以查到是那台机器,并用 from.controls("FAMQX" & adcqx.recordset.fiels(0))来找到是那个动态生成的FRAME控件,但就是坐标不知道要怎么得到!谁有思路?
      

  15.   


    倒.......你应该在逻辑上建立一个结构,用于保存每个机器的数据,比如:type MyType
       DeviceNum as string   '机器标识,唯一
        dX() as long         'X数据
        dY() as long         'Y数据
    end typedim theData() as mytype  '所有收到的X,Y数据都往这里面保存这样你的代码逻辑就非常清楚了:接收数据----->存入结构------>更新界面显示(也就是你要的图象)而要把你的这些数据一起画在一个图表上,使用我所说的这种逻辑结构,将是非常容易的事.你甚至可以再在结构里加一个表示颜色的成员,让更新界面显示的过程根据这个成员的值来显示不同的颜色,以方便区分不同机器.当然,如果你的数据库结构如果可以做此改动,就可以省去定义类型这一步.但无论如何,关键在于你代码的逻辑功能混乱了.每部分的功能都不清晰.....最后画图表了,才在这一步里去存储"最后一个点的坐标"....总之"要如何知道第几台机器的最后一个点的坐标"不在于你用什么方式去画,而是在于你如何去知道.....你使用控件,无非就是为了利用它来保存这个值.何必呢?可以用结构,也可以用数据库来保存.....最终效率都比控件好太多太多...你做得冒烟,我个人认为,主要是因为你程序的逻辑结构没整好......以上一家之言,仅供参考......:)
      

  16.   


    使用当然不能按一般的办法使用.把11楼阿勇代码里类的Dim WithEvents T As TextBox改为Public,就可以clsT(n).T.Text="xxxxx"了,与普通控件数组差不多了.本来这样的要求就要写多些代码,也不在乎多写一个对象名吧.....
      

  17.   

    '类文件DynamicTextBox代码,暂时只实现了Click事件
    Option ExplicitDim ArrayControl() As TextBox
    Dim WithEvents ArrayControlEvent As TextBox
    Dim WithEvents m_Parent As Form
    Dim m_Count As Integer
    Dim m_Name As StringPublic Event Click(ByVal Index As Integer)Public Function Add(ByVal Parent As Form, ByVal Name As String, Optional ByVal Count As Integer = 0) As Variant
        Dim i As Integer
        
        If Count < 1 Then
            Exit Function
        End If
        
        Call Delete
        m_Count = Count - 1
        ReDim ArrayControl(m_Count)
        For i = 0 To m_Count
            Set ArrayControl(i) = Parent.Controls.Add("VB.TextBox", Name & CStr(i))
            ArrayControl(i).Visible = True
        Next
        m_Name = Name
        Set m_Parent = Parent
        Add = ArrayControl
    End FunctionPublic Sub Delete()
        Dim i As Integer
        
        If m_Count < 0 Then Exit Sub
        For i = 0 To m_Count
            m_Parent.Controls.Remove ArrayControl(i)
        Next
        m_Count = -1
    End SubPrivate Sub ArrayControlEvent_Click()
        RaiseEvent Click(Val(Mid(ArrayControlEvent.Name, Len(m_Name) + 1)))
    End SubPrivate Sub ArrayControlEvent_LostFocus()
        Set ArrayControlEvent = m_Parent.ActiveControl
    End SubPrivate Sub Class_Initialize()
        m_Count = -1
    End SubPrivate Sub Class_Terminate()
        Delete
    End SubPrivate Sub m_Parent_Activate()
        If TypeName(m_Parent.ActiveControl) = "TextBox" Then
            Set ArrayControlEvent = m_Parent.ActiveControl
        End If
    End Sub'调用代码:
    Option ExplicitDim WithEvents TextBox_Array As DynamicTextBoxPrivate Sub Form_Load()
        Dim i As Integer
        Dim nTop As Long
        Dim Ctrls As Variant
        Set TextBox_Array = New DynamicTextBox
        Ctrls = TextBox_Array.Add(Me, "Text1", 10)
            
        For i = 0 To 9
            Ctrls(i).Move 0, nTop, 1500, 300
            nTop = nTop + 30 * 15
        Next i
    End SubPrivate Sub Form_Unload(Cancel As Integer)
        Set TextBox_Array = Nothing
    End SubPrivate Sub TextBox_Array_Click(ByVal Index As Integer)
        MsgBox Index
    End Sub