1. Home
  2. Computing & Technology
  3. Visual Basic
VB.NET: What Happened to Control Arrays!!!
(Part IV)
More input on Control Arrays
Selden McCabe adds his version to the series

Controls Collections! It seems to be a subject that has the power to attract a lot of attention! Another About Visual Basic Reader, Selden McCabe has written a new article that adds to everything that has been said before in Part I, Part II, and Part III of what is now a continuing series. Selden's article extends the ideas in Part I because he goes back to the concept of defining a new class to manage the controls on a form.

Selden adds a new feature to the ideas in Part I, however. But I'll let him describe it in his own words in a few paragraphs. Something that I like about Selden's article is that it is also a natural extension of the lesson from the Complete VB.NET Tutorial covering Chapter 11, Using Arrays and Collections to Manage Data. The book we're using in this tutorial has a fairly simple program that just moves controls around on a Form. Selden does much more than that. ... But let's hear it from Selden now.

--------------------------------

I found control arrays to be very useful when programming in VB 6, and really missed them when I moved to .NET. But it turns out that the object-oriented features in .NET allow us to do just about anything, including replacing the missing control arrays.

VB.NET forms do have a controls collection. But one of the first problems I ran into when trying to use it was that the controls are not all children of the Form. Controls that exist on a Tab Control, for example, are children of the Tab Control, not of the Form. So if you look in a Form's controls collection, you won't find all the controls, if they exist on a frame, tab, etc.

Fortunately, all controls have a HasChildren property. This property returns a True if the control has any child controls in it.

So using the form's controls collection, plus the HasChildren property, and recursion (see VB.NET and Recursion for an explanation of what recursion is), we can create a collection of all controls on a form with just a few lines of code.

Here is a class that does it:

Public Class ControlsCollection
    Private Shared m_controls As Collection
    Public Sub New(ByVal myForm As Form)
        m_controls = New Collection
        'create a control walker to get 
        'all controls on the form
        Dim aControlWalker As New ControlWalker(myForm)
    End Sub
    'This property returns the collection of all controls
    'on the form
    ReadOnly Property Controls() As Collection
        Get
            Return m_controls
        End Get
    End Property
    Private Class ControlWalker
        ' This class recursively walks through all controls 
        ' in a container, and all containers contained in 
        ' this container, visiting all controls throughout 
        ' the hierarchy
        Private mContainer As Object
        Public Sub New(ByVal Container As Object)
            Dim cControl As Control
            If Container.haschildren Then
                For Each cControl In Container.controls
                    'add this control to the controls collection
                    m_controls.Add(cControl)
                    If cControl.HasChildren Then
                        'This control has children, create another
                        'ControlWalk go visit each of them
                        Dim cWalker As New ControlWalker(cControl)
                    End If
                Next cControl
            End If
        End Sub
    End Class
End Class

The class ControlsCollection contains a collection (m_controls) and an internal private class named ControlWalker. The ControlWalker class does all the work.

When a new instance of the ControlWalker is created, it is handed a reference to the form. This new instance then looks at each control on the form, adding it to the m_controls collection. Then, if this control has children, a new instance of ControlWalker is created and handed this control as the container. This new ControlWalker goes through all the controls in that container, adding them to the m_controls collection.

As the new ControlWalker goes through the controls in the container, it looks to see if any of them has children. If so, it creates a new instance of the ControlWalker, handing it a reference to this container.

This process continues until no more controls and containers are found.

At this point, the ControlsCollection class has a collection, m_controls, which contains a reference to every control on the original form, no matter how deeply nested within other controls.

To add the ControlClass to your form, add a private instance of it, construct it in the Form_Load, and add a ReadOnly property to expose it's Controls collection from the form, as shown in the following code:

Private m_ControlsCollection As ControlsCollection
Private Sub Form1_Load( _
    ByVal sender As System.Object, _
    ByVal e As System.EventArgs) _
    Handles MyBase.Load
    'create the controlscollection class
    m_ControlsCollection = New ControlsCollection(Me)
End Sub

Public ReadOnly Property MyControls() As Collection
    Get
        Return m_ControlsCollection.Controls
    End Get
End Property

An example of how you could access the Controls collection from Form1 would look like this:

Dim fTest As New Form1
fTest.Show()
Dim aControl As Control
For Each aControl In fTest.MyControls
    Debug.WriteLine(aControl.Name)
Next aControl

Any time you want to have a Controls collection for a Form, you can add the ControlsCollection class to the form, and your Form now has a MyControls property.

--------------------------------

I haven't explored Selden's ideas as much as I'd like to. There are some interesting and sometimes unexpected things that can happen. For example, I discovered that it's possible to put the VB.NET compiler itself into an infinite recursion by trying to include the last segment of Selden's code into the Form1 Load event.

That was fun!

This series is still growing because a lot of you are writing in about it! Perhaps someone else will write in with more!

Explore Visual Basic
By Category
About.com Special Features

Stay connected and entertained with reviews on tips on the latest HDTVs, cellphones and more. More >

Easy ways to connect two computers for networking purposes. More >

  1. Home
  2. Computing & Technology
  3. Visual Basic

©2009 About.com, a part of The New York Times Company.

All rights reserved.