winforms 为什么控件不想被删除?

btxsgosb  于 2023-05-29  发布在  其他
关注(0)|答案(5)|浏览(223)

我试图删除所有的控制,是包含在我的winform面板,但他们根本不想得到删除-其中一些被删除,其中一些没有。我已经尝试了两种方法,但都没有:
1.前

foreach (Control controlEntry in this.contentsPanel.Controls)
{
    this.contentsPanel.Controls.Remove(controlEntry);
}

1.为

for (int i = 0; i < this.contentsPanel.Controls.Count; i++)
{
    this.contentsPanel.Controls.RemoveAt(i);
}

为什么会这样?

vzgqcmou

vzgqcmou1#

您必须小心这样的代码,像这样从它们的容器中删除控件会产生不可恢复的资源泄漏。Controls.Remove/At()或其他poster建议的Controls.Clear()方法将控件从集合中移除,并将其重新托管到“parking window”。一个原本看不见的窗口,本地窗口可以找到一个好客的家,而不必被摧毁。准备在另一个父节点上重新托管。
这是一个陷阱,你通常不会把它移到另一个父节点。控件将继续在停车窗口上生存,消耗本机Windows资源。垃圾回收器无法恢复这些资源。当Windows拒绝为您的进程提供更多窗口时,最终您的程序将崩溃。异常消息将显示“创建句柄时出错”。
相反,您必须 * 释放 * 控件。这也会自动从其父控件中移除该控件。正确的代码是:

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

如果你觉得这看起来有点奇怪,也可以向后迭代。

vltsax25

vltsax252#

每次从集合中移除控件时,集合都会更改。当你删除Controls的第一个元素时,第二个元素变成了第一个,所以当你继续删除第二个控件时,你实际上是从原始集合中删除了第三个元素(跳过了第二个元素)。
如果要删除集合中包含的所有控件,请使用this.contentsPanel.Controls.Clear()。如果你想在ControlCollection中按索引删除控件,首先选择要删除的控件以分隔列表或数组,然后删除它们。

gkl3eglg

gkl3eglg3#

如果你想把它们全部删除,那就去做吧

this.contentsPanel.Controls.Clear()
cbwuti44

cbwuti444#

foreach将失败,因为您正在更改集合,这会破坏迭代器。
for失败,因为您只删除了所有其他项;考虑:i=0,您删除第零个项目。现在,的项目1是项目0 -所以当你删除项目1(下一个循环迭代),你已经跳过了一个。
简短版本:使用Clear()

contentsPanel.Controls.Clear();

较长版本:向后迭代:

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

第一个(清晰)更简单。

bakd9h0s

bakd9h0s5#

如果是网页浏览器控件,则contentsPanel.Controls.Clear()不能释放文件; contentsPanel.Controls.Remove(i);
use while(contentsPanel.Controls.Count > 0)contentsPanel.Controls[0].Dispose();

相关问题