-1

I need help with my tool. I have try change Color my Panel with ColorDialog but, it does not work I want change colors all Panel in my Form. Panel constuctor:

Panel p = new Panel();

Event handlers:

private void button104_Click_1(object sender, EventArgs e)
{
   this.bg.FullOpen = true;
   if (this.bg.ShowDialog() == DialogResult.OK)
   {
      this.setBgColor(this.bg.Color);
   }
}

public void setBgColor(Color rgb)
{
   p.BackColor = rgb;
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • 3
    WPF, Win Forms, Xamarin, something else? – Dmitry Bychenko Sep 19 '19 at 12:26
  • @RandyRetro's You do not post screenshots fo your code, we have a codeblocks for that, please use them. – Prophet Lamb Sep 19 '19 at 12:35
  • @RandyRetro's Welcome to Stack Overflow. Please don't post screenshots of code. You can edit your question and add more text to it. This site handles source code very well, and it's much easier for everybody to read, or to copy if they want to test it for themselves so they can help you. – 15ee8f99-57ff-4f92-890c-b56153 Sep 19 '19 at 12:36
  • @EdPlunkett I was faster ;) – Prophet Lamb Sep 19 '19 at 12:38
  • Sorry, i'm new on this website x) so how i can change all BackColor of all my Panel in my Form i use ColorDialog it's working if i add "Panel1" or "Panel2" but i want change all Panel it's not work :/ – Randy Retro's Sep 19 '19 at 12:42
  • although it looks like Windows Forms because of the `EventArgs e`, still, please answer the question from the first comment... – Mong Zhu Sep 19 '19 at 12:47
  • @RandyRetro's Look if you havnt explicitly defined the backcolor of a control/container it will adopt the backcolor of ist parent or the default color if it has none, so if you which to change all backcolors it should be sufficient to change the backcolor of the outermost container. Furthermore in my opinion you should start getting used to WPF since it is the only option if you want to go proffessional, for some smackhead tools Forms is fine, but it has many limitations. – Prophet Lamb Sep 19 '19 at 12:53
  • @RenéCarannante " since it is the only option if you want to go proffessional, for some smackhead tools Forms is fine" unless about 90% of the legacy code that you are forced to maintain in your new job is written in Winforms ;) I wonder how many professional developers have the freedom to develop only **new** applications or rewrite to WPF without having to maintain legacy code in Winforms. – Mong Zhu Sep 19 '19 at 13:39
  • @RenéCarannante I feel with you, "not to start their carrier with a legacy enviroment." I am just saying that sometimes you simply cannot choose what legacy is waiting for you, and it helps to be prepared ;) – Mong Zhu Sep 19 '19 at 14:10
  • 1
    @MongZhu True that, but if you want to create best choose something new, which he persumably is trying to do. I can code a bit of C++ and fairly good C# what do I work with? FoxPro, you most definitly cant choose what to work with. But in your time off you can have fun. – Prophet Lamb Sep 19 '19 at 14:17
  • 1
    Even legacy systems will at some point move foreward to the newest eviroment and you can earn yourself some sweet reputation and some extra € if you already have the knowhow. – Prophet Lamb Sep 19 '19 at 14:20

3 Answers3

3

You can select all controls of a particular type by using the System.Linq extension method, OfType, and if you iterate over them in a loop, you can set all their BackColor properties:

private void button1_Click(object sender, EventArgs e)
{
    ColorDialog cd = new ColorDialog();

    if (cd.ShowDialog() == DialogResult.OK)
    {
        foreach (var panel in Controls.OfType<Panel>())
        {
            panel.BackColor = cd.Color;
        }
    }
}

Note that this only iterates over the controls belonging directly to the form itself. If any of the panels are inside a container control, then we will need to look through each control to see if it contains any panels.

We can write a helper method for this that takes in a Control to inspect, a Color to use for the BackColor, and a Type that specifies the type of control we want to set the back color for.

Then we first check if the Control is the same type as the one we're looking for, and if it is, set it's backcolor. After that, we loop through all it's children and recursively call the method again on them. This way, if we pass the parent form as the Control, we will iterate through all the controls:

private void SetBackColorIncludingChildren(Control parent, Color backColor, Type controlType)
{
    if (parent.GetType() == controlType)
    {
        parent.BackColor = backColor;
    }

    foreach(Control child in parent.Controls)
    {
        SetBackColorIncludingChildren(child, backColor, controlType);
    }
}

private void button1_Click(object sender, EventArgs e)
{
    ColorDialog cd = new ColorDialog();

    if (cd.ShowDialog() == DialogResult.OK)
    {
        // Pass 'this' to the method, which represents this 'Form' control
        SetBackColorIncludingChildren(this, cd.Color, typeof(Panel));
    }
}
Rufus L
  • 36,127
  • 5
  • 30
  • 43
1

You can use this:

private void button1_Click(object sender, EventArgs e)
{
  this.bg.FullOpen = true;
  if ( this.bg.ShowDialog() == DialogResult.OK )
  {
    setBgColor(Controls, bg.Color);
  }
}

public void setBgColor(Control.ControlCollection controls, Color rgb)
{
  foreach ( Control control in controls )
  {
    if ( control is Panel )
      ( (Panel)control ).BackColor = rgb;
    setBgColor(control.Controls, rgb);
  }
}

It parses all controls of the form and for each it parses all controls of the controls recursively.

Then the color of all panels of the form is changed, all "root" panels and all panels in panels in panels in panels...

  • Why could you parse all controls, if he already has the reference, all is fine... – Prophet Lamb Sep 19 '19 at 13:04
  • To change the backcolor of all Panel in the form, including panels in panels and so on, or I didn't understand the question. –  Sep 19 '19 at 13:09
  • Upvoted as I'd forgotten to account for the nested controls, and thought all controls were available in the `Controls` array on the form itself. (in my defence, not done winforms for several years now) – GPW Sep 19 '19 at 13:25
0

This looks like winforms. Assuming this is the case, you need to iterate over all the controls on the form, and for each that is a Panel, set its color.

Something like this (untested, you may need to play about a bit )

public void setBgColor(Color rgb)
{
    foreach (Control c in this.Controls)
    {
        if (c.GetType() == typeof(System.Windows.Forms.Panel))
        {
            c.BackColor = rgb;
        }
    }
}
GPW
  • 2,528
  • 1
  • 10
  • 22
  • No problem - if this helped feel free to accept the answer :) – GPW Sep 19 '19 at 12:52
  • I have one last question that I also have Panel in MetroTabPage and he no want change color – Randy Retro's Sep 19 '19 at 13:01
  • @RandyRetro's if it's not the same type of control, then extend the code to check against other types (e.g. `else if (c.GetType() == typeof(MetroControls.MetroPanel))` or similar. I'm not familiar with the Metro controls, but just had a very quick fiddle with them and I'm not sure how to even make a MetroPanel show a different background colour - it doesn't seem to change for me if I just set it in the designer; maybe that's the problem? – GPW Sep 19 '19 at 13:13
  • I'd suggest adopting Olivier Rogier's solution above - that might well cure your problem. – GPW Sep 19 '19 at 13:26
  • My Panel is in MetroTabPage1 and my Panel is a System.Windows.Form – Randy Retro's Sep 19 '19 at 13:32