user5454571
user5454571

Reputation:

Looping through all Combo boxes on a VB form

I am making a grade application for a school project and I am wondering how I can loop through and check a value in all combo boxes on a certain form, I have 19 units to check; trying to be efficient without making 19 case statements. I have tried an array and me.controls.

Upvotes: 0

Views: 3139

Answers (4)

Joel Coehoorn
Joel Coehoorn

Reputation: 415630

You already have the OfType(OF T) method. You use it like this:

ForEach box As ComboBox In MyForm.Controls.OfType(Of ComboBox)()

Next

But this only checks the direct children of your control. If you have container controls like GroupBox, Panels, FlowControlLayoutPanel, etc, you'll miss the controls nested inside them. But we can build a new OfType() method to search these recursively:

Public Module ControlExtensions
    <Extension()> 
    Public Iterator Function OfTypeRecursive(Of T As Control)(ByVal Controls As ControlCollection) As IEnumerable(Of T)
        For Each parent As Control In Controls
            If parent.HasChildren Then
                For Each child As Control In OfTypeRecursive(Of T)(parent.Controls)
                    Yield child
                Next child
            End If
        Next parent

        For Each item As Control In Controls.OfType(Of T)()
            Yield item
        Next item
    End Function
End Module

And you use it the same way:

ForEach box As ComboBox In MyForm.Controls.OfTypeRecursive(Of ComboBox)()

Next

Upvotes: 1

rheitzman
rheitzman

Reputation: 2297

Note that if you have controls host by containers (TabControl, SPlitPanel, etc.) you may not find all of your controls.

Here is a recursive call that should return all of your controls:

Sub GetControlList(container As Control, ByVal ctlList As List(Of Control))
    For Each child As Control In container.Controls
        ctlList.Add(child)
        If (child.HasChildren) Then
            GetControlList(child, ctlList)
        End If
    Next
End Sub

I have on occasion had problems with the controls on SplitContainer panels so if you use a splitter make sure you are getting all your controls.

Once you have a complete list of controls you can operate on them. This sample is working with DataGridView controls:

Dim ctrls As New List(Of Control)
GetControlList(Me, ctrls)
For Each dgv As DataGridView In ctrls.OfType(Of DataGridView)()
    AddHandler dgv.DataError, AddressOf DataGridView_DataError
    Debug.Print(dgv.Name)
Next

FYI the generic data error code:

Private Sub DataGridView_DataError(sender As Object, e As DataGridViewDataErrorEventArgs)
    Dim dgv As DataGridView = sender
    Dim sGridName As String = dgv.Name.Replace("DataGridView", "")
    Dim col As DataGridViewColumn = dgv.Columns(e.ColumnIndex)
    Dim sColName As String = col.HeaderText
    MsgBox(sGridName & vbNewLine & "Column " & sColName & vbNewLine & e.Exception.Message, MsgBoxStyle.Exclamation)
End Sub

Upvotes: 1

Artail
Artail

Reputation: 133

You'll probably want to check containers for controls of the type you're looking for, here's a little function that should do the trick for you.

Private Function GetControls(Of T)(container As Control, searchChildren As Boolean) As T()
    Dim Controls As New List(Of T)

    For Each Child As Control In container.Controls
        If TypeOf Child Is T Then
            DirectCast(Controls, IList).Add(Child)
        End If

        If searchChildren AndAlso Child.HasChildren Then
            Controls.AddRange(GetControls(Of T)(Child, True))
        End If
    Next

    Return Controls.ToArray()
End Function

Here's the usage, if search children is True then all child containers will be searched for the control you're looking for. Also, for the top most container we'll just pass in Me assuming you're calling the code from within your Form, otherwise you could pass the Form instance or a specific Panel, GroupBox, etc.

Dim ComboBoxes As ComboBox() = GetControls(Of ComboBox)(Me, True)

Upvotes: 0

Abdellah OUMGHAR
Abdellah OUMGHAR

Reputation: 3745

Try this :

For Each c As Control In Me.Controls.OfType(Of ComboBox)()
    'You cann acces to ComboBox her by c
Next

Upvotes: 3

Related Questions