Reputation: 24789
I have a panel which displays Form
objects. When the Close()
method is called on a form, the panel.Controls.Count
is modified, the Count is one less. How is this possible?
This is the way I show a form in th panel:
// 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);
And when somewhere form.Close()
is called, the Controls
count of pnlContent
is 0. So, how is this possible? What all happens when Close()
is called?
Upvotes: 4
Views: 225
Reputation: 941457
The Controls collection performs two important jobs. First it keeps track of the child controls of a container. The order of the control objects in the collection determines their Z-order. Secondly, it takes care of ensuring that controls are disposed when their parent is destroyed. Which is the reason that you don't have to dispose controls yourself like you often need to do with other .NET classes that implement IDisposable.
Which leads to a nasty bug in your code, the Controls.Clear() method just removes controls from the collection, it does not dispose them. That a very bad leak that will make your program fat and slow, eventually causing it to crash when Windows refuse to give it any more window handles. You'll need to write it like this:
while (this.pnlContent.Controls.Count > 0) this.pnlContent.Controls[0].Dispose();
Which now also makes it obvious why the control count goes down when you call the Close() method, that disposes the form object which automatically removes it from its container's Control collection.
Disposing a control just destroys the native Windows operating system resources used by the control. The Handle property being the most obvious one. It does not otherwise make the .NET object disappear, that requires the garbage collector to run. Keeping a reference to a disposed control is a bad idea, the GC won't destroy it as long as there's a reference to it and you're apt to get an ObjectDisposedException when you try to use it anyway.
Upvotes: 1
Reputation: 113402
Closing a form causes the form to be disposed, which in turn causes it to be removed from its parent's control-collection.
If you use a decompiler, you will notice two things:
ControlCollection
, the control's owner is set as the ControlCollection's
owner. ControlCollection.Add(Control value)
calls value.AssignParent(this.owner)
.ControlCollection
. Essentially, Control.Dispose
calls parent.Controls.Remove(this)
.Lesson learned: Don't use a ControlCollection as general purpose collection-type for Controls. It is deeply integrated into WinForms for control-containment and parent-child relationships. Use this type only when you genuinely require a parent control to contain a child control.
Upvotes: 5
Reputation: 410
When a form is closed, all resources created within the object are closed and the form is disposed
http://msdn.microsoft.com/pt-br/library/system.windows.forms.form.close.aspx
Upvotes: 1