Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 动态分配控件的引用_Vb.net_Reference_Controls - Fatal编程技术网

Vb.net 动态分配控件的引用

Vb.net 动态分配控件的引用,vb.net,reference,controls,Vb.net,Reference,Controls,我有一个桌面应用程序,其中一个选项卡控件和四个选项卡中有许多文本框,因为每个选项卡都是完全相同的副本 目前,我正在将逐行控件分配给相应的控件数组,以便轻松访问活动选项卡的控件。每个选项卡代表一个购物篮。我现在有四个标签。lvBasket1在第一个标签上,lvBasket2在第二个标签上,等等 我的部分代码: Private Sub InitControlsArrayAndEventHandlers() lvBasket(0) = lvBasket1 lvBasket(1) = l

我有一个桌面应用程序,其中一个选项卡控件和四个选项卡中有许多文本框,因为每个选项卡都是完全相同的副本

目前,我正在将逐行控件分配给相应的控件数组,以便轻松访问活动选项卡的控件。每个选项卡代表一个购物篮。我现在有四个标签。lvBasket1在第一个标签上,lvBasket2在第二个标签上,等等

我的部分代码:

Private Sub InitControlsArrayAndEventHandlers()
    lvBasket(0) = lvBasket1
    lvBasket(1) = lvBasket2
    lvBasket(2) = lvBasket3
    lvBasket(3) = lvBasket4

    btnSave(0) = btnSave1
    btnSave(1) = btnSave2
    btnSave(2) = btnSave3
    btnSave(3) = btnSave4

    For i As Integer = 0 To 3
        AddHandler lvBasket(i).MouseDoubleClick, AddressOf lvBasket_MouseDoubleClick
        AddHandler btnSave(i).Click, AddressOf btnSave_Click
    Next
End Sub
问题是;是否有可能在for循环中为其数组分配控制引用。与javascript中的eval类似:

lvBasket(i) = Eval("lvBasket" & i)
btnSave(i) = Eval("btnSave" & i)

看起来您已经有3个控件引用:

  • 控件集合中的一个
  • 数组中的那个
  • 可能是显示的
    lvBasketN
    变量
  • 由于从controls集合获取控件非常容易,因此实际上不需要单独的控件集合。要将一组新添加的控件连接到事件处理程序(给定名称,我假设
    Listviews
    ):


    我现在有四个选项卡。lvBasket1位于第一个选项卡上,lvBasket2位于第二个选项卡上,等等。
    [原始帖子中没有编辑]

    要跟踪分散在不同控件集合中的控件,请使用
    列表(共T个)
    ,并在创建控件时添加它们。如果在创建控件时连接事件处理程序,则根本不需要循环

    Private baskets As New List(of Listview)
    ...
    
    Dim lv As New ListView  ' e.g lvbasjket1
    lv.Name = "ziggy"
    ... many props
    AddHandler lv.MouseDoubleClick, AddressOf lvBasket_MouseDoubleClick
    baskets.Add(lv)                    ' add to secondary collection
    BasketTab1.Controls.Add(lv)        ' add to controls collection
    
    lv = New ListView       ' ie lvBasket2
    ...
    baskets.Add(lv)
    BasketTab2.Controls.Add(lv)
    
    处理程序是在创建控件时添加的,因此不需要任何循环,尽管您可以在循环中创建它们并将它们添加到列表中

    列表比数组更容易使用,但是
    baskets(0)
    将引用创建的第一个,而
    baskets(1)
    将引用第二个等。您可以对按钮、文本框等执行相同的操作,但它们仍然在每个TabPage的控件集合中组合在一起,因此无需创建其他引用即可轻松获取它们:

    ' do something to basket one on tabpage 1
    Dim n = 1
    Dim lv = TabControl2.TabPages(n - 1).Controls().OfType(Of ListView)().FirstOrDefault()
    
    If lv IsNot Nothing Then
        ' do something wonderful
    End If
    

    看起来您已经有3个控件引用:

  • 控件集合中的一个
  • 数组中的那个
  • 可能是显示的
    lvBasketN
    变量
  • 由于从controls集合获取控件非常容易,因此实际上不需要单独的控件集合。要将一组新添加的控件连接到事件处理程序(给定名称,我假设
    Listviews
    ):


    我现在有四个选项卡。lvBasket1位于第一个选项卡上,lvBasket2位于第二个选项卡上,等等。
    [原始帖子中没有编辑]

    要跟踪分散在不同控件集合中的控件,请使用
    列表(共T个)
    ,并在创建控件时添加它们。如果在创建控件时连接事件处理程序,则根本不需要循环

    Private baskets As New List(of Listview)
    ...
    
    Dim lv As New ListView  ' e.g lvbasjket1
    lv.Name = "ziggy"
    ... many props
    AddHandler lv.MouseDoubleClick, AddressOf lvBasket_MouseDoubleClick
    baskets.Add(lv)                    ' add to secondary collection
    BasketTab1.Controls.Add(lv)        ' add to controls collection
    
    lv = New ListView       ' ie lvBasket2
    ...
    baskets.Add(lv)
    BasketTab2.Controls.Add(lv)
    
    处理程序是在创建控件时添加的,因此不需要任何循环,尽管您可以在循环中创建它们并将它们添加到列表中

    列表比数组更容易使用,但是
    baskets(0)
    将引用创建的第一个,而
    baskets(1)
    将引用第二个等。您可以对按钮、文本框等执行相同的操作,但它们仍然在每个TabPage的控件集合中组合在一起,因此无需创建其他引用即可轻松获取它们:

    ' do something to basket one on tabpage 1
    Dim n = 1
    Dim lv = TabControl2.TabPages(n - 1).Controls().OfType(Of ListView)().FirstOrDefault()
    
    If lv IsNot Nothing Then
        ' do something wonderful
    End If
    

    是,使用
    Me.Controls。查找
    如下:

    Option Strict On
    
    Public Class Form1
    
      Sub New()
    
        ' This call is required by the designer.
        InitializeComponent()
    
        ' Add any initialization after the InitializeComponent() call.
        Call InitControlsArrayAndEventHandlers()
      End Sub
      Private lvBasket(-1) As ListView
      Private btnSave(-1) As Button
    
    
      Private Sub InitControlsArrayAndEventHandlers()
        Dim i As Integer = 1
        Do
          Dim ctl() As Control = Me.Controls.Find("lvBasket" & i.ToString, True)
          If ctl.GetUpperBound(0) = -1 Then Exit Do 'finished      
          ReDim Preserve lvBasket(i - 1)
          lvBasket(i - 1) = DirectCast(ctl(0), ListView)
          ctl = Me.Controls.Find("btnSave" & i.ToString, True)
          ReDim Preserve btnSave(i - 1)
          btnSave(i - 1) = DirectCast(ctl(0), Button)
          i += 1
        Loop
    
        For i = 0 To lvBasket.GetUpperBound(0)
          AddHandler lvBasket(i).MouseDoubleClick, AddressOf lvBasket_MouseDoubleClick
          AddHandler btnSave(i).Click, AddressOf btnSave_Click
        Next
      End Sub
    
      Private Sub btnSave_Click(sender As Object, e As EventArgs)
        MsgBox(DirectCast(sender, Button).Name)
      End Sub
    
      Private Sub lvBasket_MouseDoubleClick(sender As Object, e As MouseEventArgs)
        MsgBox(DirectCast(sender, ListView).Name)
      End Sub
    End Class
    

    是,使用
    Me.Controls。查找
    如下:

    Option Strict On
    
    Public Class Form1
    
      Sub New()
    
        ' This call is required by the designer.
        InitializeComponent()
    
        ' Add any initialization after the InitializeComponent() call.
        Call InitControlsArrayAndEventHandlers()
      End Sub
      Private lvBasket(-1) As ListView
      Private btnSave(-1) As Button
    
    
      Private Sub InitControlsArrayAndEventHandlers()
        Dim i As Integer = 1
        Do
          Dim ctl() As Control = Me.Controls.Find("lvBasket" & i.ToString, True)
          If ctl.GetUpperBound(0) = -1 Then Exit Do 'finished      
          ReDim Preserve lvBasket(i - 1)
          lvBasket(i - 1) = DirectCast(ctl(0), ListView)
          ctl = Me.Controls.Find("btnSave" & i.ToString, True)
          ReDim Preserve btnSave(i - 1)
          btnSave(i - 1) = DirectCast(ctl(0), Button)
          i += 1
        Loop
    
        For i = 0 To lvBasket.GetUpperBound(0)
          AddHandler lvBasket(i).MouseDoubleClick, AddressOf lvBasket_MouseDoubleClick
          AddHandler btnSave(i).Click, AddressOf btnSave_Click
        Next
      End Sub
    
      Private Sub btnSave_Click(sender As Object, e As EventArgs)
        MsgBox(DirectCast(sender, Button).Name)
      End Sub
    
      Private Sub lvBasket_MouseDoubleClick(sender As Object, e As MouseEventArgs)
        MsgBox(DirectCast(sender, ListView).Name)
      End Sub
    End Class
    

    下面是我如何实现解决方案的。我的实际控件命名时没有下划线,如lvBasket1

    Imports System.Linq.Expressions
    
    Private _txtNameSurname(BasketCount), _txtPhone(BasketCount) As TextBox
    Private _btnSelectCustomer(BasketCount), _btnAddProduct(BasketCount) As Button
    Private _lblInfo(BasketCount) As Label
    Private _lvBasket(BasketCount) As ListView
    
    Private Sub AssignControl(Of ControlType)(index As Integer, controlArrayFunc As_
            Expression(Of Func(Of ControlType())))
    
        Dim controlArray = controlArrayFunc.Compile()()
        Dim keyword = CType(controlArrayFunc.Body, MemberExpression).Member.Name.TrimStart("_"c)
    
        controlArray(index) =_
            Me.Controls.Find(keyword & (index + 1), True).OfType(Of ControlType).Single()
    End Sub
    
    Private Sub InitControlsArrayAndEventHandlers()
        For i As Integer = 0 To BasketCount
            AssignControl(i, Function() _lvBasket)
    
            AssignControl(i, Function() _txtNameSurname)
            AssignControl(i, Function() _txtPhone)
    
            AssignControl(i, Function() _btnSelectCustomer)
            AssignControl(i, Function() _btnAddProduct)
    
            AssignControl(i, Function() _lblInfo)
    
            AddHandler _lvBasket(i).MouseDoubleClick, AddressOf vlBasket_Click
    
            AddHandler _btnSelectCustomer(i).Click, AddressOf btnSelectCustomer_Click
        Next
    End Sub
    

    下面是我如何实现解决方案的。我的实际控件命名时没有下划线,如lvBasket1

    Imports System.Linq.Expressions
    
    Private _txtNameSurname(BasketCount), _txtPhone(BasketCount) As TextBox
    Private _btnSelectCustomer(BasketCount), _btnAddProduct(BasketCount) As Button
    Private _lblInfo(BasketCount) As Label
    Private _lvBasket(BasketCount) As ListView
    
    Private Sub AssignControl(Of ControlType)(index As Integer, controlArrayFunc As_
            Expression(Of Func(Of ControlType())))
    
        Dim controlArray = controlArrayFunc.Compile()()
        Dim keyword = CType(controlArrayFunc.Body, MemberExpression).Member.Name.TrimStart("_"c)
    
        controlArray(index) =_
            Me.Controls.Find(keyword & (index + 1), True).OfType(Of ControlType).Single()
    End Sub
    
    Private Sub InitControlsArrayAndEventHandlers()
        For i As Integer = 0 To BasketCount
            AssignControl(i, Function() _lvBasket)
    
            AssignControl(i, Function() _txtNameSurname)
            AssignControl(i, Function() _txtPhone)
    
            AssignControl(i, Function() _btnSelectCustomer)
            AssignControl(i, Function() _btnAddProduct)
    
            AssignControl(i, Function() _lblInfo)
    
            AddHandler _lvBasket(i).MouseDoubleClick, AddressOf vlBasket_Click
    
            AddHandler _btnSelectCustomer(i).Click, AddressOf btnSelectCustomer_Click
        Next
    End Sub
    

    就像javascript中的eval一样
    (编辑)否。VB和C#的类型更强,因此您需要实际的参考。最接近的是
    tabPage.Controls(“lvBasket”&i.ToString())
    ,它将返回
    Control
    (或Nothing),然后需要将其强制转换为该类型以使用特定的类型属性。我尝试过lvBasket(i)=Me.Controls(“lvBasket”&i+1))但是应用程序结束时没有任何错误……这是因为它们不在表单(
    Me
    )控件集合中(如果它们在选项卡上)。答案(和注释)显示了如何从tabpage控件集合获取它们。你不需要一个接一个地分配它们。我忘了提到,但是lvBasket1在第一个选项卡上,lvBasket2在第二个选项卡上等等。
    像javascript中的eval一样
    (编辑)不。VB和C的类型更强,所以你需要一个实际的参考。最接近的是
    tabPage.Controls(“lvBasket”&i.ToString())
    ,它将返回
    Control
    (或Nothing),然后需要将其强制转换为该类型以使用特定的类型属性。我尝试过lvBasket(i)=Me.Controls(“lvBasket”&i+1))但是应用程序结束时没有任何错误……这是因为它们不在表单(
    Me
    )控件集合中(如果它们在选项卡上)。答案(和注释)显示了如何从tabpage控件集合获取它们。你不需要一个接一个地分配它们。我忘了提到,但是lvBasket1在第一个选项卡上,lvBasket2在第二个选项卡上,等等。是的,我。控制。查找(“lvBasket”&I,True)工作得很好。True参数确实起到了作用,因为它也在搜索子控件。是的,Me.controls.Find(“lvBasket”&i,True)工作得很好。True参数确实起到了作用,因为它也在搜索子控件。