Andy said:
Hi to All,
I found the following issue, is this a bug?
Create a new project and, in the main form, add a listbox with a few sample
items. In the DoubleClick event of the listbox, add:
Me.Dispose()
Then run the project, double click on an item in the listbox to close the
window and then an Exception occurs.
What is the problem? I would like to close the form by double clicking on
the listbox...
Thank you,
Andy
I have a guess at what's happening, and a possibly workaround.
I think what's happening is that when your DoubleClick handler is
executing, the call stack has the context of the ListBox's event
handler, which is busy looping through the Multicastdelegate object that
holds the list of DoubleClick events. You call the Close() or Dispose()
method on the Form, which in turn disposes the ListBox control.
When your event handler returns, it goes back to the ListBox control's
code that's looping through events. But since that object has been
disposed - bang... an exception. My guess is that this situation is
explicitly handled in a button's click event handler, since that's the
way Forms are normally closed.
If this is what's happening, then I'd agree that it's a bug, and should
be fixed by MS.
However, in the meantime you can use the following code to get the
Close() method to be called after you return from your DoubleClick event
handler (watch for word wrap):
Public Class Form1
Inherits System.Windows.Forms.Form
Delegate Sub CloseDelegate() ' declare a delegate type that
matches the Close() method
'
' whatever else you need in your class
'
Private Sub ListBox1_DoubleClick(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles ListBox1.DoubleClick
' invoke the Close() method through an async delegate
Me.BeginInvoke(CType(AddressOf Me.Close, CloseDelegate))
End Sub
End Class
This calls the Close() method() through an async delegate, so it'll be
called at sometime after your call to BeginInvoke(). One thing to be
aware of is that I'm not sure if this is bullet-proof. It's not clear
to me that this will always complete all ListBox events before invoking
your async delegate.
To make that kind of guarantee would require a more complex set of
safeguards, probably involving timers, locks, and/or hooking the event
chain higher up the class hierarchy.