Event debugging help

P

proxyuser

I'm maintaining an existing form that seems to use a strange design.
Somehow it's set up so that as soon as DialogResult is set (or at least set
to OK), something fires the Close event (I assume) and the dialog closes. I
can see nothing in the form code that would do such a thing. The form
subscribes to the Closing event for the dialog, which is the event that is
actually getting captured. How can I debug so as to find out what/who is
firing this Close or Closing event? thx
 
P

Peter Duniho

proxyuser said:
I'm maintaining an existing form that seems to use a strange design.
Somehow it's set up so that as soon as DialogResult is set (or at least set
to OK), something fires the Close event (I assume) and the dialog closes. I
can see nothing in the form code that would do such a thing. The form
subscribes to the Closing event for the dialog, which is the event that is
actually getting captured. How can I debug so as to find out what/who is
firing this Close or Closing event? thx

If you set a breakpoint on the event handler, then in the call stack
will be all of the code raising the event. There's a decent chance that
whatever's closing the form is in that call stack.

In the event that it's not, that would suggest that the closing is
happening by posting a window message rather than sending it. In that
case, you'd have to set a breakpoint on the DialogResult property setter
and watch what happens as it's executed.

(At a lower level you can set a break-point on the PostMessage Win32
function, but that's not so simple to do when debugging managed code in VS).

Either way, you'll find it useful to have source-debugging for .NET
enabled. Fortunately, Microsoft has recently updated this so that it
works through most of the .NET 3.5 library versions.

I suspect what you'll find is that this is coded into the Form base
class. It is quite natural and expected that this would happen.
Especially since the MSDN documentation explains: "If the form is
displayed as a dialog box, setting this property with a value from the
DialogResult enumeration sets the value of the dialog box result for the
form, hides the modal dialog box, and returns control to the calling form".

http://msdn.microsoft.com/en-us/library/system.windows.forms.form.dialogresult.aspx

I suggest that if you don't want the window closed, then don't set the
DialogResult property. That property doesn't make any sense at all
until the dialog has been closed (and no sense whatsoever at any point
for a modeless window).

Pete
 
P

proxyuser

Peter Duniho said:
I suspect what you'll find is that this is coded into the Form base class.
It is quite natural and expected that this would happen. Especially since
the MSDN documentation explains: "If the form is displayed as a dialog
box, setting this property with a value from the DialogResult enumeration
sets the value of the dialog box result for the form, hides the modal
dialog box, and returns control to the calling form".

http://msdn.microsoft.com/en-us/library/system.windows.forms.form.dialogresult.aspx

I didn't know that setting the value was supposed to do that. However, it
doesn't really explain what I'm seeing. The doc also says "The Close method
is not automatically called when the user clicks the Close button of a
dialog box or sets the value of the DialogResult property." So then why is
the FormClosing event firing? When I set the DialogResult in a button click
handler, I exit that handler, then FormClosing is handled, and then
VisibleChanged is handled. That implies that something is closing my dialog
box before it is hiding the dialog box.
 
P

proxyuser

proxyuser said:
I didn't know that setting the value was supposed to do that. However, it
doesn't really explain what I'm seeing. The doc also says "The Close
method is not automatically called when the user clicks the Close button
of a dialog box or sets the value of the DialogResult property." So then
why is the FormClosing event firing? When I set the DialogResult in a
button click handler, I exit that handler, then FormClosing is handled,
and then VisibleChanged is handled. That implies that something is
closing my dialog box before it is hiding the dialog box.

Actually FormClosing is handled first, then FormClosed, then VisibleChanged
last.
 
P

Peter Duniho

proxyuser said:
I didn't know that setting the value was supposed to do that. However, it
doesn't really explain what I'm seeing. The doc also says "The Close method
is not automatically called when the user clicks the Close button of a
dialog box or sets the value of the DialogResult property." So then why is
the FormClosing event firing?

For better or worse, the event is overloaded. That is, you will get a
FormClosing and FormClosed event, even if the form is simply being
hidden, _if_ the form had been displayed modally.

For example, see the documentation for the FormClosing event: "You can
override the value assigned to the DialogResult property when the user
clicks the Close button by setting the DialogResult property in an event
handler for the FormClosing event of the form".
(http://msdn.microsoft.com/en-us/library/system.windows.forms.form.formclosing.aspx)

Since the documentation also says that a form that's _really_ been
closed (i.e. disposed) may not have a valid way to access the
DialogResult property (due to the form being disposed), the logical
conclusion is that you should expect the FormClosing event even if the
form isn't being disposed, i.e. when it's "closed" (i.e. hidden) in the
case of a modal dialog.

I think the API would have been more clear if there had simply been two
different classes, one for modal and one for modeless. But since they
are using the same class for either purpose, and since they didn't put
in events that are specifically for use with one purpose or the other,
the events have to do double-duty.

For a modal dialog, you will get the FormClosing and FormClosed events
when the window is being hidden, rather than when it's being disposed.
And of course, setting the DialogResult hides the window (as if the user
had dismissed it).

Note that the semantics are preserved across the entire API for the Form
class. The Close() method also only hides the window if the form was
being displayed modally. Only calling Dispose() will truly dispose the
form, if it had been shown modally. In that respect, the FormClosing
and FormClosed events are literally correct, and give the developer what
they really want in 99.9% of the cases.

Pete
 
P

proxyuser

Peter Duniho said:
For better or worse, the event is overloaded. That is, you will get a
FormClosing and FormClosed event, even if the form is simply being hidden,
_if_ the form had been displayed modally.

For example, see the documentation for the FormClosing event: "You can
override the value assigned to the DialogResult property when the user
clicks the Close button by setting the DialogResult property in an event
handler for the FormClosing event of the form".
(http://msdn.microsoft.com/en-us/library/system.windows.forms.form.formclosing.aspx)

I have to admit this has been eye opening because I never understood that,
but it's also a little surprising, and I find it confusing - I think they
could have done this differently. The basic pattern of

DialogResult = DialogResult.xxx
Close()

is used by all the developers I know because we thought it had to be coded
this way, and none of them knew it worked this way. Oh well, thanks for the
explanation!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top