如果窗体关闭,为什么控件计数会减少
本文关键字:控件 为什么 窗体 如果 | 更新日期: 2023-09-27 18:26:59
我有一个显示Form
对象的面板。当在窗体上调用Close()
方法时,panel.Controls.Count
会被修改,Count会少一个。这怎么可能?
这是我在面板中显示表单的方式:
// insertForm is a windows form
insertForm.TopLevel = false;
insertForm.Dock = DockStyle.Fill;
insertForm.FormBorderStyle = FormBorderStyle.None;
this.pnlContent.Controls.Clear();
this.pnlContent.Controls.Add(insertForm);
当调用某个form.Close()
时,pnlContent
的Controls
计数为0。那么,这怎么可能呢?调用Close()
时会发生什么?
关闭一个窗体会导致该窗体被释放,进而导致该窗体从其父控件集合中删除。
如果你使用反编译器,你会注意到两件事:
- 将控件添加到
ControlCollection
时,控件的所有者将设置为ControlCollection's
所有者。CCD_ 10调用CCD_ - 当一个控件被释放时,它会将自己从其所有者的
ControlCollection
中移除。本质上,Control.Dispose
调用parent.Controls.Remove(this)
经验教训:不要将ControlCollection用作控件的通用集合类型它与WinForms深度集成,用于控制包含和父子关系。只有当您真正需要父控件包含子控件时,才使用此类型。
当窗体关闭时,对象内创建的所有资源都将关闭,窗体将被处理
http://msdn.microsoft.com/pt-br/library/system.windows.forms.form.close.aspx
Controls集合执行两项重要的工作。首先,它跟踪容器的子控件。控制对象在集合中的顺序决定了它们的Z顺序。其次,它注意确保控件在其父控件被销毁时得到处理。这就是为什么您不必像处理其他实现IDisposable的.NET类那样自己处理控件的原因。
这会导致代码中出现一个严重的错误,Controls.Clear()方法只是从集合中删除控件,而不处理它们。这是一个非常严重的泄漏,会使你的程序变得又胖又慢,最终导致它在Windows拒绝提供更多窗口句柄时崩溃。你需要这样写:
while (this.pnlContent.Controls.Count > 0) this.pnlContent.Controls[0].Dispose();
这也清楚地说明了为什么当您调用Close()方法时控件计数会下降,该方法会处理表单对象,并自动将其从容器的control集合中删除。
处理控件只会破坏控件使用的本机Windows操作系统资源。Handle属性是最明显的一个。否则,它不会使.NET对象消失,这需要运行垃圾收集器。保留对已处理控件的引用是个坏主意,只要有对它的引用,GC就不会销毁它,而且当你试图使用它时,你很容易得到ObjectDisposedException。