5

I have an ordinary Panel control with a bunch of user controls contained within. At the moment, I do the following:

panel.Controls.Clear();

but this has the effect that I see (albeit quickly) each control disappearing individually.

Using SuspendLayout and ResumeLayout does not have any noticeable effect.

Question: Is there a way I can remove ALL controls, and have the container update only when all child controls have been removed?

Edit: the controls I am removing are derived from UserControl, so I have some control over their drawing behaviour. Is there some function I could possibly override in order to prevent the updating as they are removed?

Charlie Salts
  • 13,109
  • 7
  • 49
  • 78
  • 4
    You are leaking windows when you do this. Yes, it will get quite slow after a while. Instead use while (panel.Controls.Count > 0) panel.Controls[0].Dispose(); If it is still slow then simply set the panel's Visible property to false first. – Hans Passant Aug 09 '11 at 17:06
  • @HansPassant +1 Greeeeeeat!!! That did the trick!! – ɐsɹǝʌ ǝɔıʌ Feb 15 '14 at 09:52

2 Answers2

9

Thank you Hans for your suggestion - yes, it turns out I was leaking controls.

Here's what I ended up doing:

 panel.Visible = false;

 while (panel.Controls.Count > 0)
 {
    panel.Controls[0].Dispose();
 }

 panel.Visible = true;

Basically, I hide the entire panel (which is border-less) before I dispose of each control. Disposing of each control automatically removes said control from the parent container, which is nice. Finally, I make the container visible once more.

Charlie Salts
  • 13,109
  • 7
  • 49
  • 78
0

What I think you need is Double Buffering.

There are several answers concerning this already on SO like

Winforms Double Buffering, Enabling Double Buffering

and

How do I enable double-buffering of a control using C# (Windows forms)?

SuspendLayout stops the control redrawing as the children are removed but those actions are still processed in order when you call ResumeLayout. Double Buffering will stop the control painting at all until the offscreen buffer is updated. The update won't happen any quicker but it will be rendered to screen all at once from the buffer. If your machine is very slow you might still get a flicker when the buffer is rendered to the screen, like you would when loading a picture.

Community
  • 1
  • 1
Jodrell
  • 34,946
  • 5
  • 87
  • 124
  • I'm familiar with double buffering, and I've used it before. This would only address the symptom of the problem, not the cause. In this case, I want to actually *prevent* the child controls from drawing, as they are removed. Double buffering would only *hide* this drawing from the user. – Charlie Salts Aug 09 '11 at 13:46
  • You could subclass the controls and override the `OnPaint`, perhaps. – Jodrell Aug 09 '11 at 14:07