Click here to Skip to main content
Click here to Skip to main content

Controls Iteration

, 5 May 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

sergioabp
Engineer
Brazil Brazil
Make programs just for fun!

Comments and Discussions

 
GeneralI think you went a bit out of your way. PinmemberPIEBALDconsult6-May-08 11:41 
AnswerRe: I think you went a bit out of your way. Pinmembersergioabp7-May-08 3:47 
GeneralRe: I think you went a bit out of your way. PinmemberPIEBALDconsult7-May-08 5:53 
GeneralRe: I think you went a bit out of your way. Pinmembersergioabp7-May-08 8:12 
GeneralRe: I think you went a bit out of your way. PinmemberPIEBALDconsult7-May-08 8:32 
GeneralRe: I think you went a bit out of your way. PinmemberOddball22-May-08 12:24 
GeneralRe: I think you went a bit out of your way. PinmemberPIEBALDconsult22-May-08 14:01 
GeneralRe: I think you went a bit out of your way. Pinmembervsaratkar16-Jul-09 6:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141220.1 | Last Updated 5 May 2008
Article Copyright 2008 by sergioabp
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid