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






4.20/5 (3 votes)
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 CheckBox
es 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 CheckBox
es 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