12

Possible Duplicate:
Does Form.Dispose() call controls inside's Dispose()?

is there a way to do this?

Community
  • 1
  • 1
Luiscencio
  • 3,855
  • 13
  • 43
  • 74

4 Answers4

35

Both the Panel and the Form class have a Controls collection property, which has a Clear() method...

MyPanel.Controls.Clear(); 

or

MyForm.Controls.Clear();

But Clear() doesn't call dispose() (All it does is remove he control from the collection), so what you need to do is

   List<Control> ctrls = new List<Control>(MyPanel.Controls);
   MyPanel.Controls.Clear();  
   foreach(Control c in ctrls )
      c.Dispose();

You need to create a separate list of the references because Dispose also will remove the control from the collection, changing the index and messing up the foreach...

Charles Bretana
  • 143,358
  • 22
  • 150
  • 216
  • 9
    You can also use a reverse for loop, it won't mess up the indexes ;) – Louis Kottmann Aug 28 '12 at 09:41
  • **Hint:** If you don't want to remove all controls but **only some of them,** instead of calling `MyPanel.Controls.Clear();` you can add `MyPanel.Controls.Remove(c);` to the `foreach` loop just before the `c.Dispose();`. – Matt Sep 04 '19 at 07:59
  • 1
    Disposing a panel will automatically dispose all controls within its collection. :| – Dezv Jan 14 '21 at 21:08
4

You don't give much detail as to why.

This happens in the Dispose override method of the form (in form.designer.cs). It looks like this:

protected override void Dispose(bool disposing)
{
    if (disposing && (components != null))
    {
        components.Dispose();
    }

    base.Dispose(disposing);
}
Steven Evers
  • 16,649
  • 19
  • 79
  • 126
3

I don't believe there is a way to do this all at once. You can just iterate through the child controls and call each of their dispose methods one at a time:

foreach(var control in this.Controls)
{
   control.Dispose();
}
scottm
  • 27,829
  • 22
  • 107
  • 159
  • 2
    This method doesn't work in Winforms, the `foreach` loop will stop because the `this.Controls` collection has been modified. **The loop will exit early and not all Controls will have been disposed.** [`Control.Dispose()` removes the Control from its parent automatically when it's disposed](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Control.cs,5919). – jrh Mar 06 '17 at 18:08
0

You didn't share if this were ASP.Net or Winforms. If the latter, you can do well enough by first calling SuspendLayout() on the panel. Then, when finished, call ResumeLayout().

Himanshu
  • 31,810
  • 31
  • 111
  • 133
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794