Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

VB.NET - A Different Approach to Creating Control Arrays - Create controls at Design Time, Process Them as a Control Array with Shared Event Handlers

0.00/5 (No votes)
4 Sep 2015 1  
VB.NET - A different approach to creating control arrays - Create controls at Design time, process them as a control array with shared event handlers

Introduction

This is a demonstration of a method to create an array of like-named controls that are created and placed on a form at design-time, not dynamically added at run-time.

I developed this when converting a VB6 app that used control arrays extensively to VB.NET, which as we all know, does not support control arrays in the same way VB6 did.

Normally, I would create the controls in Form_Load code, setting size and location, and adding to an array.

However, the project I was working on had several arrays of controls that were not evenly spaced on the form, so I could not use nice little loops incrementing x and y locations, etc. Additionally, I was having to make frequent changes regarding the number and placement of controls.

So I decided to go at it from a different direction. Now, I add all controls at design-time, placing and sizing them as needed. But, I name them all with a common base name plus a delimiter and a numeric extension.

Examples: btnGroupA_00, btnGroupA_01, btnGroupA_02

Then in Form_Load, I process them all into an array, assigning the numeric portion of the control name to the Tag property and assigning a shared Click Event.

Now, I have an array named btnGroupA() of buttons, all sharing one Click procedure.

This code uses generic Control object types because all I needed were Click events.

To try the attached code, start a new VB project and add some buttons to Form1 named btnTest_00, btnTest_01, btnTest_02, etc. and some CheckBoxes named chkTest_00, chkTest_01, ...

Background

A different approach to creating control arrays in VB.NET.

Using the Code

To try the attached code, start a new VB project and add some buttons to Form1 named btnTest_00, btnTest_01, btnTest_02, etc. and some CheckBoxes named chkTest_00, chkTest_01.

'-----------------------------------------------------------------------
' This is a demonstration of method to create an array of like-named
' controls that are created and placed on a form at design-time, not
' dynamically added at run-time.
'
' I developed this when converting a VB6 app that used control arrays
' extensively to VB.NET, which as we all know, does not support control
' arrays in the same way VB6 did.  
'
' Normally, I would create the controls in Form_Load code, setting
' size and location, and adding to an array.
'
' However, the project I was working on had several arrays of controls
' that were not evenly spaced on the form, so I could not use nice little
' loops incrementing x ynd y locations, etc.  Additionally, I was having
' to make frequent changes regarding the number and placement of controls.
'
' So I decided to go at it from a different direction.  Now, I add all
' controls at design-time, placing and sizing them as needed.  But, I
' name them all with a common base name plus a delimiter and a numeric
' extension. ex:  btnGroupA_00, btnGroupA_01, btnGroupA_02

' Then in Form_Load, I process them all into an array, assigning the
' numeric portion of the control name to the Tag property and assigning
' a shared Click Event.
'
' Now I have an array named btnGroupA() Of buttons, all sharing one
' Click procedure.
'
' This code uses generic Control object types because all I needed
' were Click events.
'
' To try this code, start a new VB project and add some buttons to Form1
' named btnTest_00, btnTest_01, btnTest_02 etc. and some checkBoxes named
' chkTest_00, chkTest_01 ...
'
' NOTE: this is for  demo purposes only.  No error checking, type checking, etc ....
'-----------------------------------------------------------------------
Public Class Form1

    '-- Arrays that will hold like-named form controls
    Dim myButtons(0) As Control
    Dim myCheckBoxes(0) As Control

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        '-- Declare Delegates for click event handling procedures
        Dim myButtonClickProc As New System.EventHandler(AddressOf myButtons_Click)
        Dim myCheckboxClickProc As New System.EventHandler(AddressOf myCheckbox_Click)

        '-- Look for controls named "btnTest_01", "btnTest_02" ....
        MakeControlArray(Me, "btnTest", myButtons, myButtonClickProc)

        '-- Look for controls named "chkTest_01", "chkTest_02" ....
        MakeControlArray(Me, "chkTest", myCheckBoxes, myCheckboxClickProc)

        '-- quick test of indexed access to the array of buttons
        myButtons(1).BackColor = Color.Red

    End Sub

    '------------------------------------------------------------------------------
    ' MakeControlArray
    ' Loop through the controls passed container, adding the one's that match the
    ' passed name pattern "ControlName_nnn" to a temporary dictionary.
    ' Then pull the controls out of the dictionary in sorted order and
    '  - put the control into the passed array
    '  - set the control Tag property to its Array index
    '  - set the controls Click event handler to the passed delegate procedure
    '------------------------------------------------------------------------------
    Private Sub MakeControlArray(ctlContainer As Control, _
                                 ctlName As String, _
                                 ByRef ctlArray() As Control, _
                                 clickDelegate As System.EventHandler)

        Dim ctrlDict As Dictionary(Of Integer, Object) = New Dictionary(Of Integer, Object)

        For Each ctl As Control In ctlContainer.Controls
            If ctl.Name.Contains("_") Then
                Try
                    Dim parts() As String = ctl.Name.Split("_")
                    If parts.Count = 2 Then
                        If parts(0) = ctlName Then
                            ctrlDict.Add(Val(parts(1)), ctl)
                        End If
                    End If
                Catch
                End Try
            End If
        Next

        If ctrlDict.Count > 0 Then
            '-- We have the controls in the ctrlDict, but don't know in what order
            '-- the numeric keys were added.
            '-- So, we sort the keys to a List, and loop through the List to add the controls
            '-- to the array in the proper based on the _nn naming convention
            ReDim ctlArray(ctrlDict.Count - 1)

            '-- Get the list of keys from the dictionary
            Dim keys As List(Of Integer) = ctrlDict.Keys.ToList

            '-- Sort the List of keys
            keys.Sort()

            '-- Loop through the keys, getting controls from the Dictionary and
            '-- putting them in the Array
            Dim pos As Integer = 0 '-- array position
            Dim x As Integer '-- Key balue

            For Each x In keys
                Dim b As New Control
                If (ctrlDict.TryGetValue(x, b)) Then
                    b.Tag = pos '-- set the control Tag with its array index
                    AddHandler b.Click, clickDelegate '-- Set the control's Click event handler
                    ctlArray(pos) = b
                    pos += 1
                End If
            Next
        End If
    End Sub

    '------------------------------------------------------------------
    ' Shared Click procedure for all Buttons in myButtons() array
    '------------------------------------------------------------------
    Public Sub myButtons_Click(sender As Object, e As EventArgs)

        MessageBox.Show("Button: " + sender.tag.ToString)

    End Sub

    '------------------------------------------------------------------
    ' Shared Click procedure for all CheckBoxes in myCheckBoxes() array
    '------------------------------------------------------------------
    Public Sub myCheckbox_Click(sender As Object, e As EventArgs)

        MessageBox.Show("Checkbox: " + sender.tag.ToString)

    End Sub

End Class

Points of Interest

A different approach to creating control arrays in VB.NET.

History

  • 4th September, 2015: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here