动态分配控件的引用

时间:2016-09-06 15:55:39

标签: vb.net reference controls

我有一个桌面应用程序,其中我在选项卡控件中有许多文本框和四个选项卡,因为每个选项卡都是精确副本。

目前,我将逐行控件分配给相应的控件阵列,以便我可以轻松访问活动选项卡的控件。每个标签代表一个购物篮。我现在有四个标签。 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 个答案:

答案 0 :(得分:2)

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

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

    For Each lv As ListView In TabPage8.Controls.OfType(Of ListView)()
        AddHandler lv.MouseDoubleClick, AddressOf lv_MouseDoubleClick
    Next
    

    And I have four tabs for now. lvBasket1 is on the fist tab, lvBasket2 is on the second etc... [不在原帖中编辑]

    要跟踪分散在不同控件集合中的控件,请使用List(of 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)
    

    在创建控件时添加了处理程序,因此任何循环都没有 need ,但您可以在循环中创建它们并将它们添加到列表中。

    列表比数组更容易使用,但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
    

答案 1 :(得分:1)

是的,请按以下方式使用Me.Controls.Find

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

答案 2 :(得分:0)

以下是我实施解决方案的方法。我的实际控件名称没有下划线,如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