Get all controls of a specific type

I have multiple pictureboxes and I need to load random images into them during runtime. So I thought it would be nice to have a collection of all pictureboxes and then assign images to them using a simple loop. But how should I do it? Or maybe are there any other better solutions to such problem?


Solution 1:

Using a bit of LINQ:

foreach(var pb in this.Controls.OfType<PictureBox>())
{
  //do stuff
}

However, this will only take care of PictureBoxes in the main container.

Solution 2:

You could use this method:

public static IEnumerable<T> GetControlsOfType<T>(Control root)
    where T : Control
{
    var t = root as T;
    if (t != null)
        yield return t;

    var container = root as ContainerControl;
    if (container != null)
        foreach (Control c in container.Controls)
            foreach (var i in GetControlsOfType<T>(c))
                yield return i;
}

Then you could do something like this:

foreach (var pictureBox in GetControlsOfType<PictureBox>(theForm)) {
    // ...
}

Solution 3:

If you're at least on .NET 3.5 then you have LINQ, which means that since ControlCollection implements IEnumerable you can just do:

var pictureBoxes = Controls.OfType<PictureBox>();

Solution 4:

I use this generic recursive method:

The assumption of this method is that if the control is T than the method does not look in its children. If you need also to look to its children you can easily change it accordingly.

public static IList<T> GetAllControlsRecusrvive<T>(Control control) where T :Control 
{
    var rtn = new List<T>();
    foreach (Control item in control.Controls)
    {
        var ctr = item as T;
        if (ctr!=null)
        {
            rtn.Add(ctr);
        }
        else
        {
            rtn.AddRange(GetAllControlsRecusrvive<T>(item));
        }

    }
    return rtn;
}

Solution 5:

A simple function, easy to understand, recursive, and it works calling it inside any form control:

private void findControlsOfType(Type type, Control.ControlCollection formControls, ref List<Control> controls)
    {
        foreach (Control control in formControls)
        {
            if (control.GetType() == type)
                controls.Add(control);
            if (control.Controls.Count > 0)
                findControlsOfType(type, control.Controls, ref controls);
        }
    }

You can call it on multiple ways. To get the Buttons:

List<Control> buttons = new List<Control>();
findControlsOfType(typeof(Button), this.Controls, ref buttons);

To get the Panels:

List<Control> panels = new List<Control>();
findControlsOfType(typeof(Panel), this.Controls, ref panels);

etc.