Cómo crear matrices de control en VB .NET

En VB6 hay una característica llamada Control Arrays, donde su nombre controla el mismo nombre y les proporciona un valor de índice. Esto le permite establecer un valor al recorrer los controles y establecer cada valor. En VB .NET no puedo crear una matriz de control si alguien pudiera proporcionarme una solución similar.

Aquí hay una muestra que escribí para otra cosa que muestra cómo hacer algo similar y también muestra cómo hacer el controlador. Esto hace una cuadrícula de 10×10 botones que se vuelven rojos al hacer clic en ellos.

Dim IsCreated(99) As Boolean Dim Buttons As New Dictionary(Of String, Button) Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load For i As Integer = 0 To 99 Dim B As New Button Me.Controls.Add(B) B.Height = 30 B.Width = 40 B.Left = (i Mod 10) * 41 B.Top = (i \ 10) * 31 B.Text = Chr((i \ 10) + Asc("A")) & i Mod 10 + 1 Buttons.Add(B.Text, B) B.Tag = i AddHandler B.Click, AddressOf Button_Click Next End Sub Private Sub Button_Click(ByVal sender As Object, ByVal e As System.EventArgs) Dim B As Button = sender IsCreated(B.Tag) = True B.BackColor = Color.Red End Sub 

Evite utilizar los enfoques de iteración propuestos, obtendrá una colección bastante aleatoria de controles a menos que su formulario sea muy simple. Simplemente declare la matriz de control en su código e inicialícela en el constructor de formularios. Me gusta esto:

 Public Class Form1 Private OrderNumbers() As TextBox Public Sub New() InitializeComponent() OrderNumbers = New TextBox() {TextBox1, TextBox2} End Sub End Class 

Ahora puede tratar OrderNumbers como lo haría en VB6.

Tal vez esto es más simple. Para crear una matriz de control, pongo la statement de matriz de control en un módulo. Por ejemplo, si tengo un Formulario con tres cuadros de texto y deseo que los cuadros de texto formen parte de una matriz de control llamada ‘mytext’, declaro mi matriz de control en un módulo de la siguiente manera:

 Module Module1 Public mytext() As TextBox = {Form1.TextBox1, Form1.TextBox2, Form1.TextBox3} End Module 

Y, utilizo los TextBoxes de la matriz de control de la siguiente manera:

 Public Class Form1 Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load mytext(0).Text = "Hello" mytext(1).Text = "Hi" mytext(2).Text = "There" End Sub End Class 

Incluso puede recorrer el conjunto de controles, como lo haría en VB6:

 Public Class Form1 Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load For i As Integer = 0 To 2 mytext(i).Text = i + 1 Next End Sub End Class 

La belleza de usar un módulo es que los TextBoxes ni siquiera necesitan estar en la misma forma.

Con Winforms, podrías hacer esto:

 myForm.Controls _ .OfType(Of TextBox) _ .OrderBy(Function(c) c.Name) _ .Where(Function(c) c.Name.StartsWith("somePrefix")) _ .ToArray() 

En su formulario nombraría sus somePrefix1 somePrefix2 somePrefix1 , somePrefix2 , etc.

Aquí hay un artículo antiguo pero podría darle más información. El mejor método es súper fácil.

Su Formulario, o PanelControl, o cualquier otra cosa que pueda contener controles secundarios tendrá una Propiedad llamada Controls .

Puede recorrer todos los cuadros de texto de un control utilizando

‘Crear una lista de cuadros de texto, como una matriz pero mejor Dim myTextBoxControls como nueva lista

 For Each uxControl As UserControl in MyFormName.Controls If TypeOf(uControl) is TextBox myTextBoxControls.Add(uControl) End IF Next 

Ahora tiene su colección iterate-able con la que puede trabajar.

Puede acceder a un valor de TextBoxes con la propiedad EditValue .

Después de mirar lo que intentas hacer un poco más.

Probablemente quiera nombrar todos sus controles con un Prefijo, digamos abc por ahora.

 For Each uxControl As UserControl in MyFormName.Controls If TypeOf(uControl) is TextBox Then Dim tbControl As TextBox = DirectCast(uControl, TextBox) If tbControl.Name.StartsWith("abc") Then tbControl.EditValue = "the Value you want to initialize" End If End If Next 
 Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click Dim a() As Control = GetControls("textbox") For Each c As TextBox In a c.Text = c.Name Next End Sub Private Function GetControls(typeOfControl As String) As Control() Dim allControls As New List(Of Control) 'this loop will get all the controls on the form 'no matter what the level of container nesting 'thanks to jmcilhinney at vbforums Dim ctl As Control = Me.GetNextControl(Me, True) Do Until ctl Is Nothing allControls.Add(ctl) ctl = Me.GetNextControl(ctl, True) Loop 'now return the controls you want Return allControls.OrderBy(Function(c) c.Name). _ Where( _ Function(c) (c.GetType.ToString.ToLower.Contains(typeOfControl.ToLower) AndAlso _ c.Name.Contains("Box")) _ ).ToArray() End Function 

Esta es una de las características que no hizo la transición a VB.NET, exactamente 🙁 Sin embargo, puede lograr mucho de lo que habría hecho en VB6 con dos mecanismos diferentes en .NET: Looping a través de la colección de controles. y manejo de eventos de control.

Looping Through the Controls Collection
En VB.NET, cada contenedor de formulario y control tiene una colección de controles. Esta es una colección que puede recorrer y luego hacer una operación en el control, como establecer el valor.

 Dim myTxt As TextBox For Each ctl As Control In Me.Controls If TypeOf ctl Is TextBox Then myTxt = CType(ctl, TextBox) myTxt.Text = "something" End If Next 

En este ejemplo de código, itera sobre la colección de controles probando el tipo del objeto devuelto. Si encuentra un cuadro de texto, transfiéralo a un cuadro de texto y luego haga algo con él.

Manejo de eventos de control
También puede manejar eventos sobre múltiples controles con un manejador de eventos como lo haría usando la matriz de control en VB6. Para hacer esto, usará la palabra clave Handles.

 Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged, TextBox2.TextChanged, TextBox3.TextChanged Dim myTxt As TextBox = CType(sender, TextBox) MessageBox.Show(myTxt.Text) End Sub 

La clave aquí es la palabra clave Handles al final del controlador de eventos. Usted separa los diversos controles que desea manejar y el evento usando una coma. Asegúrese de que está manejando controles que tienen la misma statement de evento. Si alguna vez se preguntó qué era el remitente en cada evento, este es uno de sus usos. Emitir el argumento del remitente al tipo de control con el que está trabajando y asignarlo a una variable local. A continuación, podrá acceder y manipular el control que activó el evento tal como lo haría en VB6 si lo hubiera especificado e indexado a la matriz.

Usando estas dos técnicas, puede replicar la funcionalidad de las matrices de control en VB6. Buena suerte.