How to create Control Arrays in VB .NET

2019-01-06 21:36发布

问题:

In VB6 there is a feature called Control Arrays, where you name controls the same name and provide them an index value. This allows you to set a value by looping through the controls and setting each value. In VB .NET I can't create a control array could someone provide me with a similar solution.

回答1:

Here is a sample I wrote for something else that shows how to do something similar and shows how to do the handler as well. This makes a 10x10 grid of buttons that turn red when you click them.

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


回答2:

Avoid using the proposed iteration approaches, you'll get a fairly random collection of controls unless your form is very simple. Simply declare the control array in your code and initialize it in the form constructor. Like this:

Public Class Form1
    Private OrderNumbers() As TextBox

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

You can now treat OrderNumbers just like you could in VB6.



回答3:

Maybe this is simpler. To create a control array, I put the control array declaration in a module. For example, if I have a Form with three TextBoxes and I want the TextBoxes to be part of a control array called 'mytext', I declare my control array in a module as follows:

Module Module1

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

End Module

And, I use the TextBoxes from the control array as follows:

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

You can even loop through the control array, like you could in 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

The beauty of using a module is that the TextBoxes do not even need to be in the same form.



回答4:

With Winforms, you could do this:

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

On your form you would name your textboxes somePrefix1, somePrefix2, etc.

Here is an old article but it could give you more information. The top method is super easy.



回答5:

Your Form, or PanelControl, or anything else that can contain child controls will have a Property called Controls.

You can loop through all of the text boxes in a control by using

'Create a List of TextBoxes, like an Array but better Dim myTextBoxControls As New List

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

Now you have your iterate-able collection you can work with.

You can access a TextBoxes value with the EditValue property.

After looking at what you're trying to do a little further.

You probably want to name all of your controls with a Prefix, let's say abc for now.

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


回答6:

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


回答7:

So this is one of the features that did not make the transition to VB.NET -- exactly :-( However, you can accomplish much of what you would have done in VB6 with two different mechanisms in .NET: Looping through the controls collection and handling control events.

Looping Through the Controls Collection
In VB.NET every form and control container has a controls collection. This is a collection that you can loop through and then do an operation on the control like set the value.

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

In this code sample you iterate over the controls collection testing the type of the returned object. If you find a textbox, cast it to a textbox and then do something with it.

Handling Control Events
You can also handle events over multiple controls with one event handler like you would have using the control array in VB6. To do this you will use the Handles keyword.

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

The key here is the Handles keyword on the end of the event handler. You separate out the various controls that you want to handle and the event by using a comma. Make sure that you are handling controls that have the same event declaration. If you ever wondered what sender was for on every event well here's one of the uses for it. Cast the sender argument to the type of control that you are working with and assign it to a local variable. You will then be able to access and manipulate the control that fired the event just like you would have in VB6 if you specified and index to the array.

Using these two techniques you can replicate the functionality of control arrays in VB6. Good luck.



标签: vb.net vb6