Deborah's Developer MindScape






         Tips and Techniques for Web and .NET developers.

July 27, 2009

Finding Controls on Forms

Filed under: C#,VB.NET,WinForms @ 12:43 pm

There are often times that you need to find specific controls on a Windows Form (WinForm). For example, you may want to find all of the TextBoxes to clear their contents, set their background color, or hook up events. You may want to find all of the checkboxes to check or uncheck them. Or find all of the buttons to hook up events or change their color.

Since a Windows Form has a Controls collection, it may seem obvious to simply loop through the Control’s collection to find all of the desired controls.

But many of the controls provided in WinForms can contain other controls. Take this form for example:

image

This form contains two Panel controls. The top Panel control contains several Label controls and a ComboBox. The bottom Panel control contains Labels and TextBoxes.

If you look at the Controls collection for the form in this example, you find that it contains only two controls. Only the two Panel controls are actually on the form. The other controls are on the Panel controls. So to find those controls, you need to loop through the Controls collection of each Panel.

If you put a Tab control on a Panel control, then the TextBox controls would be on the Tab control which is on the Panel control. The easiest way to look for controls that could be on other controls which in turn could be on other controls, is to use recursion.

Recursion is basically calling a method from the method itself. (You can find a more detailed explanation here.) The following demonstrates recursion to find all of the TextBoxes on a form.

In C#:

private void ProcessControls(Control ctrlContainer)
{
    foreach (Control ctrl in ctrlContainer.Controls)
    {
        if (ctrl.GetType() == typeof(TextBox))
        {
            // Do whatever to the TextBox
        }

        if (ctrl.HasChildren)
            ProcessControls(ctrl);
    }
}

In VB:

Private Sub ProcessControls(ByVal ctrlContainer As Control)
    For Each ctrl As Control In ctrlContainer.Controls
        If TypeOf ctrl Is TextBox Then
            ‘ Do whatever to the TextBox
        End If

        ‘ If the control has children,
        ‘ recursively call this function
        If ctrl.HasChildren Then
            ProcessControls(ctrl)
        End If
    Next
End Sub

The code begins by processing each control within the defined container control using the container’s Controls collection. The control’s type is checked to determine if it is the desired type of control. This technique can be used to look for any type of control or multiple types of controls.

The HasChildren property of the control is checked to determine if the control itself is a container for other controls. If so, it calls this method recursively using the control as the container control.

This method resides in the Form and is called as follows.

In C#:

ProcessControls(this);

In VB:

ProcessControls(Me)

The form itself is passed into the ProcessControls method as the highest level container. If you only want to search for controls within some other container, pass it instead of the entire form. For example, if you only wanted to search for TextBox controls on Panel2 or on controls that are on Panel2, you would pass Panel2 instead of the form (this or me).

Finding Controls By Name

If you want to find a control or set of controls by name, there is an easier way.

In C#:

Control[] ctrls = this.Controls.Find("TextBox1", true);

In VB:

Dim ctrls() As Control = Me.Controls.Find("TextBox1", True)

This code uses the Find method of the controls collection. The first parameter defines the name of the control(s) to find. If the second parameter is true, the Find will search through all child controls, performing the recursive operation for you. If it is false, it will only look through the form’s Controls collection.

When I was first working with the Find method, I thought it odd that it returned an array since you can only put one control on the form named “TextBox1”. However, you can add multiple controls with the same name using Controls.Add. Also, if you build a composite user control you can also put a TextBox1 on the user control. So if you also have a TextBox1 on the form, the Find method will find two controls named “TextBox1”.

Enjoy!

22 Comments

  1.   wawa — February 7, 2014 @ 12:24 pm    Reply

    as knowing which container has x Control

  2.   Pedro — August 19, 2016 @ 2:33 am    Reply

    Hi! It was perfectly explain, but I have a question. I try to fin a ListBox in my form this way:

    dim list = me.controls.find(“ListBox” & 1, false)

    and then I want to add some items to that listbox, for that I try to do this:

    list(0).items.add(“item”) but it doesn’t recognize the member “items” and in consecuence the method “add()” that is available in all ListBox controls.

    I also try this

    dim list() as ListBox = me.controls.find(“ListBox” & 1, false)

    but when I run it it tells me: Unable to cast object of type ‘System.Windows.Forms.Control[]’ to type ‘System.Windows.Forms.ListBox[]’.

    What I really need is add items to the ListBox that I searched with that name.

    Could you help me? Thank you so much.

RSS feed for comments on this post. TrackBack URI

Leave a comment

© 2020 Deborah's Developer MindScape   Provided by WPMU DEV -The WordPress Experts   Hosted by Microsoft MVPs