Windows Form Designer generated code

A test application

In order to verify the above-mentioned disposable behavior, I've created a Windows Application project implementing two components (you can download the solution by clicking the download link above). The SimpleComponent class was created WITHOUT the New(IContainer) constructor. The ContainedComponent class was created WITH the New(IContainer) constructor:

Public Class SimpleComponent
Inherits System.ComponentModel.Component
Public Sub New()
    MyBase.New()
End Sub
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
    Debug.WriteLine(String.Format("{0}({1})", Me.GetType().FullName, disposing))
    MyBase.Dispose(disposing)
End Sub
End Class

Public Class ContainedComponent
Inherits System.ComponentModel.Component
Public Sub New()
    MyBase.New()
End Sub
Public Sub New(ByVal Container As System.ComponentModel.IContainer)
    Me.New()
    Container.Add(Me)
End Sub
Protected Overloads Overrides Sub Dispose( _
    ByVal disposing As Boolean)
    Debug.WriteLine(String.Format("{0}({1})", Me.GetType().FullName, disposing))
    MyBase.Dispose(disposing)
End Sub
End Class

After recompiling the solution, I was able to add the two components to the Visual Studio .NET toolbox and I've dropped both of the components onto a DialogForm form class. Here is the instantiation code that the Windows Forms designer generated for the two components:

#Region " Windows Form Designer generated code "
...
Me.components = New System.ComponentModel.Container
Me.SimpleComponent1 = New DisposableComponents.SimpleComponent
Me.ContainedComponent2 = New DisposableComponents.ContainedComponent(Me.components)
...
#End Region

Because the ContainedComponent class exposes the New(IContainer) constructor, the designer generated code to call this constructor instead of the default one. In the constructor, the ContainedComponent instance adds itself to the Form.components container, so it is automatically disposed when the Form's Dispose(Boolean) method is called.

In contrast, the SimpleComponent instance does not really know when the owning Form is disposed, so it remains alive until it becomes garbage-collected eventually.

In the application's main form, the following code is used to display the DialogForm containing the two components:

Private Sub ShowDialogButton_Click(...)
Dim Dialog As DialogForm
Try
    Dialog = New DialogForm
    Dialog.ShowDialog(Me)
Catch ex As Exception
    Trace.WriteLine(ex.ToString())
    MsgBox(ex.Message, MsgBoxStyle.Exclamation)
Finally
    If Not Dialog Is Nothing Then
    Dialog.Dispose()
    End If
End Try
End Sub

When you run the application and click the ShowDialogButton button, the DialogForm instance is displayed. If you dismiss the dialog, the DialogForm.Dispose method is called and you'll see in the Output window that the ContainedComponent.Dispose method has been called as well.

In contrast, the SimpleComponent instance is NOT disposed until after the application is ended or until garbage collection takes place. (It might happen if you create and destroy several instances of the DialogForm so enough memory is allocated that a threshold for the garbage collection is reached. Just press and hold the ENTER key and you'll reach the threshold quickly).

You might also like...

Comments

About the author

Palo Mraz

Palo Mraz United States

I live in Slovakia with my wife, two sons (fulltime), one daughter (occasionally) and a dog. I've been doing Microsoft Windows development since 1988; primarily in VB. I'm a big fan of the MS .N...

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.” - Antoine de Saint Exupéry