Each derived class inherits from the corresponding abstract base class as follows:
Inherits libCtlArray.clsTxtArray
Each derived class contains one or two constructors, depending on which container
controls are used in the client application.
e) Constructor # 1 caters for controls located on Windows
Forms
f)
Constructor
# 2 caters for controls located on Windows User Control
In addition, the constructors contain three parameters to identify the array
items
g) Control Prefix string [eg. strText]
h)
Array identifier string [eg. strArr]
The derived class constructor instantiates the corresponding base class which,
as we saw in the preceding section, populates the arrays.
'CONSTRUCTOR # 2 - USED IF CONTROLS
HOSTED ON A USER CONTROL
Public Sub New(ByRef
UserCtl As UserControl, ByVal strTxt As String,_
ByVal strArr
As String)
MyBase.New(UserCtl,
strTxt, strArr)
mHost = UserCtl
mHostName = UserCtl.Name
End Sub
Finally, by assigning the host control name to a member variable, we can then
implement logic in the event handlers to cater for the specific functionality
required for each array on each host control. The possibility of adding a
Case clause for each individual control would deny the whole exercise of adding
controls to an array, and so is not a valid option.
Public Overrides Sub
TxtValidatingHandler(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs)
'Example of SELECT CASE logic to allow for
TextBox arrays
'in different User Controls
Select Case mHostName
Case "ctlClientArrays"
MessageBox.Show("Execute validating logic here
for " & _
mHostName & ": " & _
CType(CType(sender, TextBox).Name, String),
_
"TextBox Array Validating Event")
Case "ctlClientArrays2"
' 'Add control specific
logic here
End Select
End Sub
If the number of Forms / User Controls that implement arrays becomes excessive
for one derived class, then multiple derived classes can be implemented [eg.
one derived class for all the forms under each main menu option].
While it is true that the derived classes add an extra layer, they do present
the advantage of grouping together the application event handlers for multiple
forms / user controls and thus allowing the reuse of common functionality.
Let us now look at how it all comes together in the Form or User Control which
contains the control arrays.
The
Windows Form and User Control
In order to be able to assign controls to an array at run-time the following
steps need to be completed in the class defining the host control:
1) Define a client class of the type corresponding to
the control: class TxtBoxArr1 is of type clsClientTextBoxArr. There is no
limit to the number of different array classes we can create for a Form /
User Control
2) Define the array identifier string to use (strArr).
There is no limit to the number of controls we can add to any individual array.
3) Define the prefix to identify controls to be assigned
to the array
Dim TxtBoxArr1 As clsClientTextBoxArr
Const strArr As String
= "_arr"
Const strTxt1 As String
= "TextBox1"
4) Instantiate the Array class, one for each distinct
array to be created and passing into the constructor the required parameters.
'Instantiate array class
TxtBoxArr1 = New
clsClientTextBoxArr(Me, strTxt1, strArr)
5) Carry out any initial logic on the array. For example,
the sample application displays a messagebox at startup listing the number
of array elements in each of the defined control arrays.
6) Use the control arrays whenever you need to loop through
and process all the elements. An example is when we need to load data into
the controls as part of the form load. Below is some example code which can
be used to loop through all the combo boxes assigned to an array (CboArr)
and select for each one the currently saved data, or no selection if a null
or zero value is returned from the database. Note that when retrieving the
field value, we are using the Sourcefield property to provide the field name
for each array item, rather than having to hard-code the field name. Such
functions can in turn be placed in separate utility classes, so that they
need only be written once to then be used throughout an application.
'Loop through all comboboxes in CboArr
For i = 0 To CboArr.UBound
'Select the combobox = item (i) in CboArr
With CboArr(i)
'Retrieve current saved
data, using associated SourceField
num = mdtProdCols.Rows(0)( CboArr.SourceField(CboArr(i)))
If IsDBNull(num) Then
.Tag = "0"
.SelectedIndex = -1
ElseIf CType(num,
Integer) = 0 Then
.Tag = "0"
.SelectedIndex = -1
Else
'Set Tag = saved data
.Tag = num
'Now loop through each item in the current combobox
For j = 0 To .Items.Count
- 1
'Identify which combo item is to be selected
Next
End If
End With
Next
The approach illustrated allows the user to quickly and easily create control
arrays within Form or User Controls. There is some overhead in the maintenance
of the derived classes where the user needs to implement the event handler
logic, but this exercise can also help to rationalise and reuse code whenever
possible. In addition, the coding required on the actual host Form or User
Control is minimal, and again can take advantage of generic functions which
can be written in utility classes.