In January, 2014, I posted an answer to a CP QA question that shows how to get all the Controls using a 'Stack, rather than using the usual recursive technique: [
^].
That answer has complete source code, and examples, and links to where I got the idea from, and links to discussion of using the Stack based technique by people much smarter than I will ever be.
Modifying this code to build a record of each Control Type found, and a List of instances of each Type of Control can be done like this:
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
public static class SpecialMethods
{
public static Dictionary<string,List<Control>> GetControlsByType(Control aControl)
{
return GetAllControls(aControl)
.GroupBy(typ => typ.GetType().Name)
.Select(grp => grp.ToList())
.ToDictionary(name => name[0].GetType().Name);
}
public static IEnumerable<Control> GetAllControls(Control aControl)
{
Stack<Control> stack = new Stack<Control>();
stack.Push(aControl);
while (stack.Any())
{
var nextControl = stack.Pop();
foreach (Control childControl in nextControl.Controls) stack.Push(childControl);
yield return nextControl;
}
}
}
Now we can test this using a Form (or any other Control that may have Child Controls):
private void Form1_Load(object sender, EventArgs e)
{
foreach (KeyValuePair<string,List<Control>> kvp in SpecialMethods.GetControlsByType(this))
{
Console.WriteLine("Control Type: {0} Count: {1}", kvp.Key, kvp.Value.Count.ToString());
}
}
Here's a sample output from a test:
Control Type: Form1 Count: 1
Control Type: ToolStrip Count: 2
Control Type: Button Count: 4
Control Type: TextBox Count: 1
Control Type: Label Count: 3
Control Type: GroupBox Count: 1
Control Type: Panel Count: 2
Comments:
What's happening in the 'GetControlsByType static method:
1. all the Controls are filtered into a set of IGroupings based on the name of the Type of each Control: by the GroupBy operation
2. each IGrouping is transformed into a List<Control> by the 'Select operation.
3. a Dictionary is created with the key set to the Name of the Type of the first Control in each List<Control> in each Group.