Extracting controls from the Controls collection

ddanbe 2 Tallied Votes 943 Views Share

The VS designer is a wonderful tool to use and saves you lots of time.
One drawback though. If you have a lot of the same controls and you want to change some properties of it at runtime, you got some coding to do.
Say you want to change the BackColor of 50 buttons on your form, you could do something like this:
Button1.BackColor = newColor;
Button2.BackColor = newColor;

Button50.BackColor = newColor;
With some copy and paste, this is doable, but I don’t like it.

You know you can index the Controls collection, but you don’t know how the designer has made up this Controls collection(it may contain lots of different controls), see a designer.cs file for that. You also don’t know which control is at which index.

A solution is: leave the designer for what it is and “design everything yourself”, put all your buttons in a list so you got total control(he!) over what is to be done at runtime.
C# is a wonderful language! Another approach is to use the is keyword!
Is returns a Boolean so you can use it in an if statement to check which control you have at hand.
See the code snippet how I used this to set the text of a Label in a bunch of Panels in a TabPage of a Form.

public Form1()
        {
            InitializeComponent();
            // loop through all the controls on a tabpage control of this form
            foreach (Control Cntrl in this.tabPage1.Controls)
            {
                if (Cntrl is Panel)
                {
                    // if it is a Panel control,
                    // we loop through each of its controls
                    foreach (Control C in Cntrl.Controls)
                        if (C is Label)     
                        {
                            // Adjust properties of our Label, 
                            // Parent is the Panel containing the Label
                            C.BackColor = C.Parent.BackColor;
                            C.Text = C.Parent.BackColor.Name; // works only with named colors!
                        }
                }
            }
        }
Mr.Coder 0 Newbie Poster

How would I iterate thru labels for example...?

ddanbe 2,724 Professional Procrastinator Featured Poster

Hi, Mr.Coder! Welcome here.
I'm looping through my Labels on line 11 until line 18 of my code.
Your loop may be a little different, depending on your specific situation.
I notice now I forgot the braces in the foreach loop.
Because I only have one if statement in it this is allowable, but IMHO the compiler should give a warning.

Mr.Coder 0 Newbie Poster

Silly me, I see. I was a bit frustrated. Forgive me.

Thanks!

zack_falcon 0 Junior Poster in Training

Uh, hi. I tried this code to change the background images of buttons, but it never seems to get past the 'if (Cntrl is Panel)' part

foreach (Control Cntrl in this.pnlDeadPcs.Controls)
                    {
                        if (Cntrl is Panel)
                        {
                            foreach (Control C in Cntrl.Controls)
                            {
                                if (C is Button)
                                {
                                    MessageBox.Show("In if C Button");
                                    if (iPlus < 10)
                                    {
                                        pieceName = "App_Pics/piece_" + "0" + iPlus.ToString() + "_b.png";
                                        C.BackgroundImage = Image.FromFile(pieceName);

                                    }
                                    else
                                    {
                                        pieceName = "App_Pics/piece_" + iPlus.ToString() + "_b.png";
                                        C.BackgroundImage = Image.FromFile(pieceName);
                                    }
                                    iPlus++;
                                }
                            }
                        }
                    }

iPlus is simply my way of telling how many times the foreach loop ran. It is also concatenated to the image name that is to be used for the background image of the button (button 1 uses image 1, and button 2 uses image 2).

I'm not sure if that's entirely possible, though, as I have little experience with foreach loops. Perhaps I could make / research a for loop version.

But my problem right now is that the code never gets past the first if. The difference I see there between your code and the one I used is that I used an actual Panel (pnlDeadPcs), instead of a Tab page. Is there something I did wrong?

Teme64 215 Veteran Poster

With nested controls you must be aware which Controls collection you're dealing with.

Also, Panel control doesn't support foreach syntax so you have to use for-loop

Control c;
for (int i=0; i<pnlDeadPcs.Controls.Count; i++)
{
    c = pnlDeadPcs.Controls[i];
    if (c is Button)
    {
        // Use Button c
        
    }
}

HTH

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.