
[英]Why do I get NullReferenceException when loading controls using LoadControl(string VirtualPath)?
[英]Why controls do not want to get removed?
我试图删除Winform面板中包含的所有控件,但它们根本不想删除-其中一些已删除,而另一些则没有。 我已经尝试了2种方法,但一无所获:
前言
foreach (Control controlEntry in this.contentsPanel.Controls) { this.contentsPanel.Controls.Remove(controlEntry); }
对于
for (int i = 0; i < this.contentsPanel.Controls.Count; i++) { this.contentsPanel.Controls.RemoveAt(i); }
为什么会这样呢?
您必须当心这样的代码,像这样从其容器中删除控件会导致不可恢复的资源泄漏。 Controls.Remove / At()或其他发布者建议的Controls.Clear()方法将从集合中删除控件,并将其重新托管到“停车窗口”。 否则看不见的窗口,原生窗口无需破坏即可找到好客的住所。 准备好重新托管在另一个父级上。
这是陷阱,您通常不会将其移动到另一个父对象。 该控件将继续保留在停车窗口中,从而消耗本机Windows资源。 垃圾收集器无法恢复这些资源。 最终,当Windows拒绝为您的进程提供更多窗口时,您的程序将崩溃。 异常消息将显示“错误创建句柄”。
而是,您必须处置控件。 这也会自动将控件从其父控件中删除。 正确的代码是:
while (contentsPanel.Controls.Count > 0) contentsPanel.Controls[0].Dispose();
或者,如果您发现这看起来太奇怪了,请向后迭代。
每次从集合中删除控件时,集合都会更改。 当您删除Controls
第一个元素时,第二个元素将变为第一个,因此,当您继续删除第二个控件时,实际上是从原始集合中删除了第三个元素(跳过第二个元素)。
如果要删除集合中包含的所有控件,请使用this.contentsPanel.Controls.Clear()
。 如果要通过ControlCollection
的索引删除控件,请首先选择要删除的控件以分离列表或数组,然后再删除它们。
如果您想全部删除,那就去做吧
this.contentsPanel.Controls.Clear()
因为您正在更改集合,所以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);
}
第一个(清除)比较简单。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.