为什么控件不想被删除?

时间:2011-12-11 18:23:03

标签: c# winforms controls

我正在尝试删除winform面板中包含的所有控件,但他们根本不想删除 - 其中一些被删除而其中一些没有删除。我已经尝试了两种方法,但没有:

  1. 的foreach

    foreach (Control controlEntry in this.contentsPanel.Controls)
    {
        this.contentsPanel.Controls.Remove(controlEntry);
    }
    
  2. for (int i = 0; i < this.contentsPanel.Controls.Count; i++)
    {
        this.contentsPanel.Controls.RemoveAt(i);
    }
    
  3. 为什么会这样?

4 个答案:

答案 0 :(得分:14)

你必须注意这样的代码,从容器中删除控件会产生不可恢复的资源泄漏。 Controls.Remove / At()或其他海报建议的Controls.Clear()方法从集合中删除控件并将其重新托管到“停放窗口”。一个不可见的窗口,本机窗口可以找到一个好客的家,而不必被破坏。准备重新托管在另一位家长身上。

哪个陷阱,您通常不会将其移动到另一个父级。控件将继续在停放窗口中存活,消耗本机Windows资源。垃圾收集器无法恢复这些资源。最终,当Windows拒绝为您的进程提供更多窗口时,您的程序将崩溃。异常消息将显示“创建句柄时出错”。

相反,您必须配置控件。这也会自动从其父级中删除控件。正确的代码是:

 while (contentsPanel.Controls.Count > 0) contentsPanel.Controls[0].Dispose();

如果你觉得这看起来太奇怪了,那就向后迭代。

答案 1 :(得分:7)

每次从集合中删除控件时,集合都会更改。当你删除Controls的第一个元素时,第二个元素变为第一个,所以当你继续删除第二个控件时,你实际上是从原始集合中删除第三个元素(跳过第二个元素)。

如果要删除集合中包含的所有控件,请使用this.contentsPanel.Controls.Clear()。如果要按ControlCollection中的索引删除控件,请首先选择要删除的控件以分隔列表或数组,然后将其删除。

答案 2 :(得分:4)

如果您想将它们全部删除,请执行

this.contentsPanel.Controls.Clear()

答案 3 :(得分:3)

foreach将失败,因为您正在更改集合,这会破坏迭代器。

for失败,因为你只删除所有其他项目;考虑:i = 0,你删除了第0个项目。现在 项目1的项目是项目0 - 所以当你删除项目1(下一个循环迭代)时,你已经跳过了一个。

简短版本:使用Clear()

contentsPanel.Controls.Clear();

更长的版本:向后迭代:

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

第一个(清除)更简单。