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