C# Not Disposing controls like I told it to

2019-03-02 19:23发布

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);
}

4条回答
虎瘦雄心在
2楼-- · 2019-03-02 20:12

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.

查看更多
Evening l夕情丶
3楼-- · 2019-03-02 20:14

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.

查看更多
你好瞎i
4楼-- · 2019-03-02 20:16

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.

查看更多
不美不萌又怎样
5楼-- · 2019-03-02 20:24

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);
}
查看更多
登录 后发表回答