Click here to Skip to main content
15,879,096 members
Articles / Multimedia / GDI+
Article

Controls Iteration

Rate me:
Please Sign up or sign in to vote.
2.35/5 (9 votes)
5 May 2008CPOL3 min read 46.1K   798   15   10
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:

C#
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:

C#
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):

C#
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:

C#
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.

C#
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.

C#
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:

C#
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:

C#
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.

C#
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:

C#
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)


Written By
Engineer
Brazil Brazil
Make programs just for fun!

Comments and Discussions

 
GeneralW o r k s g r e a t ! Pin
Piet Pelle24-Mar-13 4:40
Piet Pelle24-Mar-13 4:40 
GeneralSuggestions Pin
PIEBALDconsult7-May-08 7:18
mvePIEBALDconsult7-May-08 7:18 
GeneralI think you went a bit out of your way. Pin
PIEBALDconsult6-May-08 10:41
mvePIEBALDconsult6-May-08 10:41 
AnswerRe: I think you went a bit out of your way. Pin
sergioabp7-May-08 2:47
sergioabp7-May-08 2:47 
GeneralRe: I think you went a bit out of your way. Pin
PIEBALDconsult7-May-08 4:53
mvePIEBALDconsult7-May-08 4:53 
GeneralRe: I think you went a bit out of your way. Pin
sergioabp7-May-08 7:12
sergioabp7-May-08 7:12 
GeneralRe: I think you went a bit out of your way. Pin
PIEBALDconsult7-May-08 7:32
mvePIEBALDconsult7-May-08 7:32 
GeneralRe: I think you went a bit out of your way. Pin
Oddball22-May-08 11:24
Oddball22-May-08 11:24 
GeneralRe: I think you went a bit out of your way. Pin
PIEBALDconsult22-May-08 13:01
mvePIEBALDconsult22-May-08 13:01 
GeneralRe: I think you went a bit out of your way. Pin
vsaratkar16-Jul-09 5:58
vsaratkar16-Jul-09 5:58 
Thanks for the article, Very helpful for me.
Vsaratkar

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

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