In my project I have a setting called DriveLetter and I wish to insert the value of this setting in to the text of several controls on a form (replacing a placeholder).

I thought the easiest way to do this would be to loop through each control on the form and search for the placeholder, but through trial and error I have discovered that I can't do that (at least in the way I'm trying) because I make use of Containers, such as the SplitContainer and the Panel.

Below is what I have so far, which takes in to account the aforementioned SplitContainer and Panel containesr, but how can I amend this to loop through every control on the form without having to explicitly check if the current control is a type of container?

Private DRIVE_LETTER As String = My.Settings.DriveLetter

'**
' Handle form loading
''
Private Sub form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load

    ReplaceDriveLetter(Me)

End Sub

'**
' Update the value of the <DRIVE_LETTER> text placehoder
''
Private Sub ReplaceDriveLetter(ByVal ctrlContainer As Control)

    For Each ctrl As Control In ctrlContainer.Controls

        If TypeOf ctrl Is SplitContainer Or TypeOf ctrl Is Panel Then
            ReplaceDriveLetter(ctrl)
        Else
            ctrl.Text = Replace(ctrl.Text, "<DRIVE_LETTER>", UCase(DRIVE_LETTER))
        End If

    Next ctrl

End Sub
2

There are 2 best solutions below

4
On BEST ANSWER

This should do it, although obviously replace the text here with the DriveLetter (I can help with that if you'd like).

Private Sub ReplaceAllControlsOnForm()
    Dim stackOfControls As New Stack(Of Control)

    'add initial controls (all on form)
    For Each c As Control In Me.Controls
        stackOfControls.Push(c)
    Next

    'go until no controls are left
    While (stackOfControls.Count > 0)
        Dim currControl As Control = stackOfControls.Pop
        currControl.Text = "text here"
        'see if our control can contain controls
        If (currControl.Controls IsNot Nothing AndAlso currControl.Controls.Count > 0) Then
            'add all of these controls onto our stack
            For Each c As Control In currControl.Controls
                stackOfControls.Push(c)
            Next
        End If
    End While
End Sub
2
On

You can also use Control.HasChildren Property to check if a control contains one or more child controls.

As stated on MSDN, if the Controls collection has a Count greater than zero, the HasChildren property will return true. Accessing the HasChildren property does not force the creation of a Control.ControlCollection if the control has no children, so referencing this property can provide a performance benefit when walking a tree of controls.

So you can change your function in:

Private Sub ReplaceDriveLetter(ByVal ctrlContainer As Control)

    For Each ctrl As Control In ctrlContainer.Controls

        If ctrl.HasChildren Then
            ReplaceDriveLetter(ctrl)
        Else
            ctrl.Text = Replace(ctrl.Text, "<DRIVE_LETTER>", UCase(DRIVE_LETTER))
        End If

    Next ctrl

End Sub