In my windows forms app clients sometimes report a strange exception:
System.InvalidOperationException: Value Dispose() cannot be called while doing CreateHandle()
at System.Windows.Forms.Control.Dispose(Boolean disposing)
at System.Windows.Forms.ContainerControl.Dispose(Boolean disposing)
at System.ComponentModel.Component.Dispose()
at MyCompany.SomeApp.DialogBox.Show(string caption, string message)
at MyCompany.SomeApp.MainForm.Button1_Click(Object sender, MouseEventArgs e)
The code that causes this error looks like this:
namespace MyCompany.SomeApp
{
public class DialogBox : CustomForm
{
public static DialogResult Show(string caption, string message)
{
using (DialogBox dialog = new DialogBox())
{
dialog.Text = caption;
dialog.lblMessage.Text = message;
return dialog.ShowDialog();
}
}
}
}
DialogBox is basically a class that inherits from Windows.Forms.Form and does some design changes, nothing special. The excepions happens at
return dialog.ShowDialog();
and not at the end of the using
block as I would expect. It looks like somehow, within the ShowDialog()
method and before the form's handle is created, the Dispose() method is called.
But my DialogBox neither calls Dispose() itself nor swallows other exceptions, it only does some painting in the OnPaint() event.
Does anybody have some clues how to get rid of this exception?
Update:
Here is the only code in my CustomForm class (besides changes mode in the windows forms designer (added 2 Labels, a button and changed some colors)
Public Class CustomForm
Inherits System.Windows.Forms.Form
<DebuggerStepThrough()> _
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
Static pen1 As New Pen(Color.FromArgb(39, 46, 54), 21)
Static pen2 As New Pen(Color.FromArgb(44, 51, 59), 1)
Static pen3 As New Pen(Color.FromArgb(93, 99, 99), 1)
Static pen4 As New Pen(Color.FromArgb(119, 124, 127), 1)
Static pen5 As New Pen(Color.FromArgb(148, 157, 156), 1)
Static pen6 As New Pen(Color.FromArgb(175, 185, 186), 1)
With e.Graphics
.DrawRectangle(Pens.Black, 0, 0, (Me.Width - 1), (Me.Height - 1))
.DrawLine(pen1, 1, 11, Me.Width - 1, 11)
.DrawLine(pen2, 1, 22, Me.Width - 2, 22)
.DrawLine(pen3, 1, 23, Me.Width - 2, 23)
.DrawLine(pen4, 1, 24, Me.Width - 2, 24)
.DrawLine(pen5, 1, 25, Me.Width - 2, 25)
.DrawLine(pen6, 1, 26, Me.Width - 2, 26)
End With
End Sub
Private Const GWL_STYLE As Integer = (-16)
Private Const WS_CAPTION As Integer = &HC00000
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal hWnd As IntPtr, ByVal nIndex As Integer) As Integer
Public ReadOnly Property HasCaption() As Boolean
Get
return (GetWindowLong(Me.Handle, GWL_STYLE) And WS_CAPTION) = WS_CAPTION
End Get
End Property
End Class
Update: I changed the code a little bit because it was misleading.
In the stacktrace you can see that My.App.DialogBox.Show(...) is called. Which is a static method that contains the using block.
Neither DialogBox nore CustomForm override the ShowDialog() method of Form (which is why it is not shown in the stacktrace.