C# Not Disposing controls like I told it to

2019-03-02 19:36发布

问题:

I have a Panel control. And inside the panel users can add combobox's, textbox's labels etc and drag them around and stuff, and there's a Delete button on my form where if they click it, it will delete all controls inside that panel. BUT this code:

foreach( Control control in panel.Controls )
{
     control.Dispose();
}

... Does not work properly. It doesn't always Dispose of ALL the controls inside the panel. Sometimes it gets rid of most of them, sometimes it only gets rid of one or two. Sometimes all but 1 are Disposed. WTF?

EDIT:


Here is the code I use to add the controls to the Panel:

button1_Click(object sender, EventArgs e)
{
    TextBox tbox = new TextBox();
    tbox.Multiline = true;
    tbox.IsAccessible = true;

    panel.Controls.Add(tbox);
}

回答1:

A simpler way to delete all your controls is to do this:

panel.Controls.Clear();

Edit: thanks to Pieter and Paolo, just calling Clear() like this will leak memory since the controls are not disposed, so this is not a good practice.



回答2:

Dispose() only cleans up unmanaged resources (although Paul Williams noted in the comments that it is usually more complex than this!) so it may or may not do anything useful in your case.

Try removing the controls with the RemoveAt(i) method, not Dispose():

for(int i = panel.Controls.Count-1; i >= 0; i--)
{
    panel.Controls.RemoveAt(i);
}


回答3:

I have seen this before, you are removing items from acollection that make the collection itself smaller. e.g if there are 5 items in the collection as you move down through it you come to the end of the list sooner than you expect because the list gets smaller with every Dispose() you issue.



回答4:

I know is a pretty old post, but I hope could help somebody.

The only way I found that works is:

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

This way it doesn't matter if the list of Controls become smaller in the middle of the loop.