Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Controls Iteration

0.00/5 (No votes)
5 May 2008 1  
This example shows how to perform recursive controls iteration within a form
ControlsBinary

Introduction

In this article, I will show you how to perform a recursive controls iteration to get all the controls inside a form.

Background

Every form has a collection of controls inside it. This collection can be accessed through this.Controls. To retrieve them, first we are going to create a method called GetControls() (that receives a parameter of type Control.ControlCollection, here called a_oControlCollection) and then use a foreach statement to iterate through a_oControlCollection, as shown below:

private void GetControls(Control.ControlCollection a_oControlCollection)
{
    foreach(Control t_oBaseControl in a_oControlCollection)
    {

    }

This code works fine only if we don't have nested controls, which happens when we use containers, menus and toolbars. So, in this case, we have to iterate through each container to retrieve its controls. But, how can we know if the current control is a common control, a container, a menu or a toolbar? The best way I found is to use a switch statement to check the control's type, as shown in the code below:

switch(t_oBaseControl.GetType().Name)
{

}

Now, we have all the control's types and we have to create a case statement for each type that we want. For those controls that aren't a container, menu or toolbar, we can get them directly, as shown below (adding them to a ComboBox):

case "Button":
case "CheckBox":
case "CheckedListBox":
case "ComboBox":
case "DateTimePicker":
case "Label":
case "LinkLabel":
case "ListBox":
case "ListView":
case "MaskedTextBox":
case "MonthCalendar":
case "NumericUpDown":
case "PictureBox":
case "ProgressBar":
case "RadioButton":
case "RichTextBox":
case "TextBox":
case "WebBrowser":
    cbbControls.Items.Add(t_oBaseControl.Name);
    break;

For the FlowLayoutPanel, GroupBox, Panel and TableLayoutPanel, we are going to add them to the ComboBox and then recursively call the GetControls() method using their ControlCollection, like below:

case "FlowLayoutPanel":
case "GroupBox":
case "Panel":
case "TableLayoutPanel":
    cbbControls.Items.Add(t_oBaseControl.Name);
    GetControls(t_oBaseControl.Controls);
    break;

For the SplitContainer, we're going to do the same for each panel.

case "SplitContainer":
    cbbControls.Items.Add(t_oBaseControl.Name);
    GetControls(((SplitContainer)t_oBaseControl).Panel1.Controls);
    GetControls(((SplitContainer)t_oBaseControl).Panel2.Controls);
    break;

And the same for the TabControl, for each TabPage.

case "TabControl":
    cbbControls.Items.Add(t_oBaseControl.Name);
    foreach(TabPage t_oTabPage in ((TabControl)t_oBaseControl).TabPages)
    {
        cbbControls.Items.Add(t_oTabPage.Name);
        GetControls(t_oTabPage.Controls);
    }
    break;

For the *Strip components, things become annoying. For the MenuStrip, we're going to first iterate through all ToolStripItems and, for each ToolStripMenuItem, call another method called GetMenuItems() (that receives a ToolStripItemCollection), and pass as parameter the DropDownItems property. See below:

case "MenuStrip":
    cbbControls.Items.Add(t_oBaseControl.Name);
    foreach(ToolStripMenuItem t_oMenuItem in ((ToolStrip)t_oBaseControl).Items)
    {
        cbbControls.Items.Add(t_oMenuItem.Name);
        GetMenuItems(t_oMenuItem.DropDownItems);
    }
    break;

For the StatusStrip and ToolStrip, we're going to first use a for statement to iterate through all ToolStripItems. After that, we're going to use a switch statement to check its type. For the ToolStripButton, ToolStripComboBox, ToolStripLabel, ToolStripMenuItem, ToolStripProgressBar, ToolStripStatusLabel and ToolStripTextBox, we can cast them all to ToolStripItem. But for ToolStripSplitButton and ToolStripDropDownButton, we need to cast to their exact type and then call GetMenuItem() passing their DropDownItems as parameter to retrieve the controls nested, as shown below:

case "StatusStrip":
case "ToolStrip":
    cbbControls.Items.Add(t_oBaseControl.Name);
    for(int i = 0;i < ((ToolStrip)t_oBaseControl).Items.Count;i++)
    {
        switch(((ToolStrip)t_oBaseControl).Items[i].GetType().Name)
        {
            case "ToolStripButton":
            case "ToolStripComboBox":
            case "ToolStripLabel":
            case "ToolStripMenuItem":
            case "ToolStripProgressBar":
            case "ToolStripStatusLabel":
            case "ToolStripTextBox":
                ToolStripItem t_oToolStripItem =
                    (ToolStripItem)((ToolStrip)t_oBaseControl).Items[i];
                cbbControls.Items.Add(t_oToolStripItem.Name);
                break;
            case "ToolStripSplitButton":
                ToolStripSplitButton t_oToolStripSplitButton =
                    (ToolStripSplitButton)((ToolStrip)t_oBaseControl).Items[i];
                cbbControls.Items.Add(t_oToolStripSplitButton.Name);
                GetMenuItems(t_oToolStripSplitButton.DropDownItems);
                break;
            case "ToolStripDropDownButton":
                ToolStripDropDownButton t_oToolStripDropDownButton =
                    (ToolStripDropDownButton)((ToolStrip)t_oBaseControl).Items[i];
                cbbControls.Items.Add(t_oToolStripDropDownButton.Name);
                GetMenuItems(t_oToolStripDropDownButton.DropDownItems);
                break;
        }
    }
    break;

Just for example, we can also iterate through all nodes inside a TreeView. Inside a foreach statement, we call method GetNodes() passing as parameter the current TreeNode's Nodes property.

case "TreeView":
    cbbControls.Items.Add(t_oBaseControl.Name);
    foreach(TreeNode t_oTreeNode in ((TreeView)t_oBaseControl).Nodes)
    {
        cbbControls.Items.Add(t_oTreeNode.Name);
        GetNodes(t_oTreeNode.Nodes);
    }
    break;

Below are those two necessary methods mentioned earlier:

private void GetMenuItems(ToolStripItemCollection a_oToolStripItemCollection)
{
    foreach(ToolStripItem t_oToolStripItem in a_oToolStripItemCollection)
    {
        cbbControls.Items.Add(t_oToolStripItem.Name);
            switch(t_oToolStripItem.GetType().Name)
            {
                case "ToolStripMenuItem":
                   GetMenuItems(((ToolStripMenuItem)t_oToolStripItem).DropDownItems);
                   break;
            }
    }
}
private void GetNodes(TreeNodeCollection a_oTreeNodeCollection)
{
    foreach(TreeNode t_oTreeNode in a_oTreeNodeCollection)
    {
        cbbControls.Items.Add(t_oTreeNode.Name);
        GetNodes(t_oTreeNode.Nodes);
    }
}

Using the Code

To use this code, simply call GetControls() inside a form passing this.Controls as a parameter. That's all! As simple as that. I made most of the possible case statements, but a few still have to be implemented. I'll leave this as an exercise for you. Any questions? Let me know!

History

  • April 2008 - First published

Copyright © 2007 Sergio A. B. Petrovcic. All rights reserved. Do not publish to other sites without my express permission. Link to this article in accordance with this site's policies and procedures.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here