View Single Post
Old 06-24-2004, 04:10 PM
Iceplug's Avatar
Iceplug Iceplug is offline

Retired Moderator
* Guru *
Join Date: Aug 2001
Location: Iowa, USA
Posts: 16,583
Smile Control Arrays in .NET

After messing around in VB.NET, one might notice that there are no Index properties on the controls.
Incorrect Snap Conclusion one might make:
Oh... I can't make a control array!!! I can't make a list/grid of controls! No!!!

But... there are lots of ways to create a control array in .NET.

Under the hood of your form class
If you have ever spent some time looking in the Windows Forms Designer Code #region, you might notice the code required to actually set up a control on the form, in the case of a button, you will find the declaration, which is declared in the form's Declarations section:
    Friend WithEvents Button1 As System.Windows.Forms.Button
Next, instantiating the button:
        Me.Button1 = New System.Windows.Forms.Button
Then, there is the setting of the properties:
        Me.Button1.Location = New System.Drawing.Point(136, 96)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(88, 16)
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Button1"
Then, the button is added to the form.
I can do that too!
OK, surely, we should be able to do something just like this for an array of controls. I mean, a For Loop or two should accomplish this same thing for an array. Let's try it.

Declaration in the form:
    Friend WithEvents Buttons(99) As Button
Drat... an error! WithEvents cannot be typed as arrays... so, we can't use WithEvents on an array declaration.
Ah... frustrated, let's get rid of it.
    Friend Buttons(99) As Button
Another incorrect snap conclusion: So much for actually having an event handlers for this array.
We'll discuss adding events later. Back to our Button Friends.

There is the instantion, the setting of the properties, and the form getting the button added onto it; let's do all of those in the For loop:
    Dim LV As Integer
        For LV = 0 To 99 

            Buttons(LV) = New Button  'Create the button.
'It has a default width and height.
            Buttons(LV).Left = Buttons(LV).Width * (LV Mod 10)
            Buttons(LV).Top = Buttons(LV).Height * (LV \ 10)
            Buttons(LV).Name = "Btn" & LV
            Buttons(LV).Text = LV.ToString()


Ahh... that looks decent.
And... it works! Yay!
Control arrays! *Dance*
OK, now, why can't I get any events to my array?

Yes, you can get events for the buttons in the array.
    Public Sub ButtonClickEventProc(ByVal sender As Object, ByVal e As EventArgs)
    'I want this event to run for all of the controls.
    End Sub
Now, using Handles at the end of this subroutine doesn't work...
You'd only get controls declared WithEvents, and since we can't use WithEvents on the control array... how can we possibly add an event to the control?

... AddHandler.

Taking a look at event handling at runtime should popup two keywords: AddHandler and RemoveHandler... since we don't need to remove any events, AddHandler looks promising.

Let's AddHandler
So, in our For Loop, we can Add Handlers to the buttons in the array.
            AddHandler Buttons(LV).Click, AddressOf ButtonClickEventProc
And now, we have an event set up for the control array!

  • You can add a one-dimensional array of controls to the form by using Me.Controls.AddRange
  • You can modify the button that you clicked on by DirectCasting the sender into a button: Dim btn As Button = DirectCast(sender, Button)
  • You can have a multi-dimensional array of controls as well.
  • You can add a control to the control array by Declaring another button instance and doing the above to create a new control.
  • You can handle any event.
  • Your event handler procedure must have the right signature... which means the sub must have (sender As Object, e As ???), where ??? is some brand of event args (for a click, it is just EventArgs, and for a mouse event, it is MouseEventArgs)

So, here is a form with a button control array. (As a .vb file)
Imports System
Imports System.Windows.Forms

Public Class Controlland
    Inherits System.Windows.Forms.Form

    Friend Buttons(99) As Button
    'Declare the buttons.

    Public Sub New() 'This is the Sub New, the constructor, etc.

        MyBase.New()  'Initialize the form itself.


    End Sub

    Public Sub CreateArray() 'This subroutine initializes the array.

        'This will be done in a For Loop
        Dim LV As Integer  'LV is our loop variable.

        For LV = 0 To 99 'Set up the loop to go through each button in the array.

            Buttons(LV) = New Button  'Create the button.
            'This creates the button at the top left of the form with the default size.

            Buttons(LV).Left = Buttons(LV).Width * (LV Mod 10)
            Buttons(LV).Top = Buttons(LV).Height * (LV \ 10)
            'Initializes the button locations.

            Buttons(LV).Name = "Btn" & LV
            Buttons(LV).Text = LV.ToString()

            'Add an event handler and whatever you may want to add.
            AddHandler Buttons(LV).Click, AddressOf ButtonClickEventProc
            'This event handler handles the click event of all of the buttons.


        'Add... ALLLL of the buttons to the form.

    End Sub

    Public Sub ButtonClickEventProc(ByVal sender As Object, ByVal e As EventArgs)
        'Button control array event handler.
        'sender has to be recast as a Button
        Dim Btn As Button = DirectCast(sender, Button)
        Btn.Enabled = False

    End Sub

    Public Shared Sub Main()
        Dim F As Controlland = New Controlland
    End Sub

End Class

Iceplug, USN
Quadrill 1 Quadrill 2 (full) Quadrill 3 JumpCross .NET Website is ALIVE! - DL Platform Tour for VB.NET! Posting Guidelines Hint: Specify your location in your user cp profile if you want compassion!

Last edited by Colin Legg; 07-31-2010 at 01:43 PM. Reason: tidied up code tags
Reply With Quote