how to hide all panels in windows form?
Asked Answered
B

4

6

In my windows application which uses menu strip and multiple panel containers, a panel is displayed depending on menu option

hiding all panels by manually passing names is very time consuming, is there any way to hide all panels or any way to get names of all panels in a form??

Bathtub answered 6/6, 2013 at 19:35 Comment(2)
I have edited your title. Please see, "Should questions include “tags” in their titles?", where the consensus is "no, they should not".Landan
Have you looked into using a foreach loop?Potentiate
H
10
foreach (Control c in this.Controls)
{
    if (c is Panel) c.Visible = false;
}

And you could even make that recursive, and pass in the ControlCollection instead of using this.Controls:

HidePanels(this.Controls);

...

private void HidePanels(ControlCollection controls)
{
    foreach (Control c in controls)
    {
        if (c is Panel)
        {
            c.Visible = false;
        }

        // hide any panels this control may have
        HidePanels(c.Controls);
    }
}
Heptastich answered 6/6, 2013 at 19:40 Comment(4)
Ninja'ed. I was writing that code just now. So now you have my upvote.Blameworthy
Rather than writing a method to recursivly traverse a control's structure for each type of think you want to do it's a lot easier to just write the method once to get all controls (at any depth).Bicentenary
@Brian, right back at ya friend, that's why Stack Overflow has a badge called Sportsmanship!Heptastich
@Servy, I don't particularly disagree with you. I +1'd your answer as it's quite elegant and I'll probably grab that code on down the line one day.Heptastich
B
5

So presumably you want to get all of the controls anywhere on the form, not just top level controls. For that we'll need this handy little helper function to get all child controls, at all levels, for a particular control:

public static IEnumerable<Control> GetAllControls(Control control)
{
    Stack<Control> stack = new Stack<Control>();
    stack.Push(control);

    while (stack.Any())
    {
        var next = stack.Pop();
        yield return next;
        foreach (Control child in next.Controls)
        {
            stack.Push(child);
        }
    }
}

(Feel free to make it an extension method if you think you'd use it enough.)

Then we can just use OfType on that result to get the controls of a particular type:

var panels = GetAllControls(this).OfType<Panel>();
Bicentenary answered 6/6, 2013 at 19:46 Comment(4)
Nice way to use a loop rather than recursion (thereby avoiding a potential stack overflow, though if you managed to have that deep of a control hierarchy, you should probably step back and take a breather...)! I think it could be a tiny bit better if you took in the type as generic and only pushed controls that matched the requested type on to the stack. Maybe it's not needed though, hrm....Footlambert
@Footlambert That wouldn't work. What if there's a user control at the top level with a panel in it. Do you want that panel or not? If you do, then you can't filter out the panels you're looking for right away, you need to do it at the end. Of course if you don't want to return the control unless it, and all of its parents, are all of the specified type, then that's a different story. That would certainly be faster (you look through a lot less controls), but it's also very different in terms of the results.Bicentenary
@Footlambert Also note that avoiding recursion not only prevents any possible SO exceptions, it's also just generally more performant. Not by a huge margin, but to a degree. It also prevents the messy stack traces when debugging or dealing with exceptions.Bicentenary
well, doing this psychically, wouldn't a simple wrapper using is around the yield return an--- oh, oooooh! I get it, yeah, you need to push them all on the stack (obviously), but I was mixing up the stack with only protecting the yield - doing that wouldn't save a whole lot of effort over using the .OfType extension method. Carry on!Footlambert
C
3

Its clean to write something like this

foreach (Panel p in this.Controls.OfType<Panel>()) {
    p.Visible = false;
}
Constantina answered 6/6, 2013 at 19:41 Comment(0)
P
1

Argh! I was just writing the code too! :P

Control[] aryControls = new Control[]{ controlnamehere1, controlnamehere2 };
foreach (Control ctrl in aryControls)
{
   ctrl.Hide();
}

Or, alternatively:

Control[] aryControls = new Control[]{ controlnamehere1, controlnamehere1 };
foreach (Control ctrl in aryControls)
{
   ctrl.Visible = false;
}
Potentiate answered 6/6, 2013 at 19:42 Comment(2)
how do you know that control contains panel1, button1? why are you creating new Control[] array, its memory uneffective, are you trying to learn bad habits - to unnecessarily waste memory?Centner
Edited to be more clear. Are you now just looking at my answers to be snarky?Potentiate

© 2022 - 2024 — McMap. All rights reserved.