How to: Retrieve all controls in a form, using generics (I)


Note: This is a very common question in MSDN forums. For this reason I decided to write this post, and use it for reference in future questions.

tshirt

The typical question: How to clear the content of all the textboxes in a form?

Answer: Using generics it’s really easy… First of all, let’s create an extensor method, that will returns a collection of all the controls of a type in a Form (or container). And after, we will use this collection to do an action over each returned item.

The extensor method:

public static List<T> GetControls<T>(this Control container) where T : Control
{
    List<T> controls = new List<T>();
    foreach (Control c in container.Controls)
    {
        if (c is T)
            controls.Add((T)c);
        controls.AddRange(GetControls<T>(c));
    }
    return controls;
}

This method retrieves the collection of Controls of a control and then, it call itself recursively, retrieving the content of all his containers.

How to use it:

this.GetControls<TextBox>().ForEach(p => p.Text = string.Empty);

In this code, we will use the extensor method directly in a form (because Form class inherits from ContainerControl, that inherits from ScrollableControl, and ScrollableControl from Control). Or, in other words, our Form will implement our extensor method. So, at compile time, we should specify the type of the controls we want to retrieve (in the example we use TextBox, but you can use Button type instead), and then, use ForEach to apply an action on each one of the items returned.

Moreover, if we want to retrieve only the controls into a container (GroupBox, Panel, TabControl or another), we should call the method for this particular control.

this.GroupBox1.GetControls<TextBox>().ForEach(p => p.Text = "hello");
this.Panel1.GetControls<TextBox>().ForEach(p => p.Text = string.Empty);

Applying several actions on each control:

In most cases, we would apply several actions to each control (not only one). In this case, it’s quite easy: The only thing we have to do is create a method that receives a parameter of this type, and call it passing the control as an argument:

this.GetControls<TextBox>().ForEach(p => ApplyFormat(p));

private void ApplyFormat(TextBox text)
{
    text.BackColor = Color.LightGray;
    text.ForeColor = Color.Red;
    text.Text = "hello";
    text.TextAlign = HorizontalAlignment.Center;
}

Or maybe, using an ‘action delegate’, both options are correct:

this.GetControls<TextBox>().ForEach(p =>
{
    p.BackColor = Color.LightGray;
    p.ForeColor = Color.Red;
    p.Text = "hello";
    p.TextAlign = HorizontalAlignment.Center;
});

Happy coding! :-)

November 2010

Advertisements

One thought on “How to: Retrieve all controls in a form, using generics (I)

  1. Pingback: How to: Retrieve all controls in a form, using generics (II) – Linq at rescue « Lluis Franco's Corner

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s