By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,719 Members | 1,036 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,719 IT Pros & Developers. It's quick & easy.

dialog's Form.FormClosed is not run

P: n/a
I have created a new form from the main form. When I close the main
form with the 'x' close button, its Form.FormClosed event is run, but
not the dialog's.

Is this normal? It is ok / dangerous? How can I force shutdown code
within the dialog's Form.FormClosed event run?

Zytan

Mar 31 '07 #1
Share this Question
Share on Google+
11 Replies


P: n/a
On Fri, 30 Mar 2007 18:17:22 -0700, Zytan <zy**********@gmail.comwrote:
I have created a new form from the main form. When I close the main
form with the 'x' close button, its Form.FormClosed event is run, but
not the dialog's.

Is this normal? It is ok / dangerous? How can I force shutdown code
within the dialog's Form.FormClosed event run?
Use FormClosing on the dialog. Modal dialogs are hidden, not closed.

Alternatively, if you dispose the modal dialog, that should eventually
cause the FormClosed event to run. It's just that the form isn't actually
closed right away, because modal dialogs generally involve code extracting
data values from the dialog *after* the dialog has been dismissed (so it
it were actually closed, the dialog window wouldn't be around to get the
values from).

Pete
Mar 31 '07 #2

P: n/a
Use FormClosing on the dialog. Modal dialogs are hidden, not closed.

I think you mean modeless dialogs. Modal dialogs are closed. My
About dialog does run FormClosing and FormClosed, and it must be
constructed again if I want to make it appear again.

So FormClosing happens when the modeless dialog is made invisible by
Hide(). I've confirmed that. It just doesn't make sense, though.
Why does FormClosing happens when the dialog is NOT being closed?
And, when the dialog is eventually shut down by the application
terminated (which I'd like to know how, and when) why doesn't both
FormClosing and FormClosed get run? FormClosing is the only one of
the two that is EVER run, and it only runs on Hide(), not when the app
shuts down.
Alternatively, if you dispose the modal dialog, that should eventually
cause the FormClosed event to run.
Yes, calling Close() destroys the modal About dialog, and FormClosing
and FormClosed runs. Is 'dispose' what happens when you call Close()?
It's just that the form isn't actually
closed right away, because modal dialogs generally involve code extracting
data values from the dialog *after* the dialog has been dismissed (so it
it were actually closed, the dialog window wouldn't be around to get the
values from).
Again, I think you mean modeless dialogs. Understood. But, the same
is also true of modal dialogs. When DOES call FormClosed, and it does
destrcut / dispose, since you have to create a new one if you want to
see it again.

Thanks, Pete

Zytan

Mar 31 '07 #3

P: n/a
I think you mean modeless dialogs. Modal dialogs are closed. My
About dialog does run FormClosing and FormClosed, and it must be
constructed again if I want to make it appear again.
Actually, my About dialog is also modeless. I can go back to the main
form as I please. If I close the app, neither of ITS FormClosed or
FormClosing is called, either. So, I guess these dialogs are really
one and the same. There's probably a property I can set to restrict
foucs to the About dialog while it's open, and then it'd act just as a
modal dialog should, and all is well (the FormClosed and FormClosing
are guaranteed to be run).

Now, for modeless dialogs, we have a different story. By calling
Form.Close() they do NOT dispose. It's the same as clicking the 'x'
close button, or calling Form.Hide(). FormClosing event is triggered,
but the dialog still remains, hidden. FormClosed is not called.

Zytan

Mar 31 '07 #4

P: n/a
On Sat, 31 Mar 2007 10:53:18 -0700, Zytan <zy**********@gmail.comwrote:
>Use FormClosing on the dialog. Modal dialogs are hidden, not closed.

I think you mean modeless dialogs. Modal dialogs are closed.
No, they are not. From MSDN: "When a form is displayed as a modal dialog
box, clicking the Close button (the button with an X at the upper-right
corner of the form) causes the form to be hidden and the DialogResult
property to be set to DialogResult.Cancel."

http://msdn2.microsoft.com/en-us/lib...rmclosing.aspx
My About dialog does run FormClosing and FormClosed, and it must be
constructed again if I want to make it appear again.
But how do you display it? Modally or modeless? Do you keep the
reference to the form?
So FormClosing happens when the modeless dialog is made invisible by
Hide(). I've confirmed that.
It also happens when the modeless dialog is "closed" (but not actually
closed).
It just doesn't make sense, though.
Why does FormClosing happens when the dialog is NOT being closed?
Because that's where the dialog result is set. See link above.
And, when the dialog is eventually shut down by the application
terminated (which I'd like to know how, and when) why doesn't both
FormClosing and FormClosed get run?
Because FormClosing has already been run.
FormClosing is the only one of
the two that is EVER run, and it only runs on Hide(), not when the app
shuts down.
It should run any time the modal dialog is dismissed (whether by Hide() or
clicking the close button or whatever).

If your application terminates normally, which means it waits until all
forms are closed, then you should get the FormClosed event for all the
forms. If your application does not terminate normally, then lots of
things are prevented from executing, and I'm not surprised the FormClosed
event is one of those things.

If it's not working like that, then I have no explanation. I'm not an
expert in how the underlying forms stuff works. I just know what I've
done and what the docs say.
>Alternatively, if you dispose the modal dialog, that should eventually
cause the FormClosed event to run.

Yes, calling Close() destroys the modal About dialog, and FormClosing
and FormClosed runs. Is 'dispose' what happens when you call Close()?
Yes. The modal dialog's resources are not disposed of until the form is
actually closed.
Again, I think you mean modeless dialogs. Understood.
I don't mean modeless dialog. A modeless dialog (or form) is just a form
that has been shown using Show rather than ShowDialog.
But, the same
is also true of modal dialogs. When DOES call FormClosed, and it does
destrcut / dispose, since you have to create a new one if you want to
see it again.
Yes, with both modal and modeless dialogs (forms) the resources are
disposed of when the form is closed. The difference is that with a modal
dialog (form), the form is not actually closed at the point in time that
it visually appears to be closed. The actual closing doesn't happen until
later.

Pete
Mar 31 '07 #5

P: n/a
Use FormClosing on the dialog. Modal dialogs are hidden, not closed.
>
I think you mean modeless dialogs. Modal dialogs are closed.

No, they are not. From MSDN: "When a form is displayed as a modal dialog
box, clicking the Close button (the button with an X at the upper-right
corner of the form) causes the form to be hidden and the DialogResult
property to be set to DialogResult.Cancel."

http://msdn2.microsoft.com/en-us/lib...rmclosing.aspx
I am confused. It continues to say: "When the Close method is called
on a Form displayed as a modeless window, you cannot call the Show
method to make the form visible, because the form's resources have
already been released."

But, what's the difference? Both modal and modeless can exist always
and just be hidden away when not in use. The only real difference is
that one steals focus and doesn't let it go, where as the other
doesn't. So, what does that have to do with the way they are handled
when you call Close()?
My About dialog does run FormClosing and FormClosed, and it must be
constructed again if I want to make it appear again.

But how do you display it? Modally or modeless? Do you keep the
reference to the form?
1. My main form has a reference to a second form for the entire time.
When I call Close() on this second form, it just goes hidden (calls
FormClosing), but it remains. I can make it come back with Show().

2. I have an About form that only has a reference inside of an event
handler for the 'about' button. When I call Close() on it, it calls
FormClosing then FormClosed.

They are both modeless (they don't steal focus and keep it). So, it
must be the reference to the 'second form' that keeps it from call
FormClosed. Since, for the about form, its reference goes away when
the 'about' button' event handler returns.
So FormClosing happens when the modeless dialog is made invisible by
Hide(). I've confirmed that.

It also happens when the modeless dialog is "closed" (but not actually
closed).
Yes.
It just doesn't make sense, though.
Why does FormClosing happen when the dialog is NOT being closed?

Because that's where the dialog result is set. See link above.
http://msdn2.microsoft.com/en-us/lib...logresult.aspx
"The dialog result of a form is the value that is returned from the
form when it is displayed as a modal dialog box."

Ok, that makes sense, it's like the result you get from calling
MessageBox.Show(). That's a modal dialog.

In both of my cases, the dialogs are modeless (although the about box
really should be modal).
And, when the dialog is eventually shut down by the application
terminated (which I'd like to know how, and when) why doesn't both
FormClosing and FormClosed get run?

Because FormClosing has already been run.
(To be sure we're on the same page, I'm talking about my modeless
dialogs, here, which may or may not be different from modal.) I have
a Debug.WriteLine for both FormClosing and FormClosing, and I would
see if either is run at all, ever, and neither is run. In this case,
I make the dialog appear, and close the whole app:

DialogForm constructing. <-- it only constructs
MainForm constructing.
MainForm closing.
MainForm closed.

But, it is run, if I click 'x' to close it, or my Hide button that
calls Hide(). In this case, I repeatedly make it appear, and close
it:

DialogForm constructing.
MainForm constructing.
DialogForm closing. <-- me clicking 'x'
DialogForm closing. <-- me calling Hide(), after making it appear
again
DialogForm closing. <-- and so on.
MainForm closing.
MainForm closed.

So, FormClosing is only for, for my modeless dialog, when I call
Hide() or press 'x'. It has a reference to it in the MainForm (as you
can see, since even it is constructed before the MainForm is!)
FormClosing is the only one of
the two that is EVER run, and it only runs on Hide(), not when the app
shuts down.

It should run any time the modal dialog is dismissed (whether by Hide() or
clicking the close button or whatever).
Yes, it is.
If your application terminates normally, which means it waits until all
forms are closed, then you should get the FormClosed event for all the
forms.
Pressing 'x' on the main form terminates the app, and for all modeless
dialogs that are open, they do not get FormClosing or FormClosed. I
can verify this by calling MessageBox.Show or Debug.WriteLine in these
events. So, is pressing 'x' a 'normal termination'? Or should I
'catch' this, and instruct all forms to close?
If your application does not terminate normally, then lots of
things are prevented from executing, and I'm not surprised the FormClosed
event is one of those things.
Please define "not terminating normally". Maybe this is my issue.
If it's not working like that, then I have no explanation. I'm not an
expert in how the underlying forms stuff works. I just know what I've
done and what the docs say.
I think maybe you're dealing with modal dialogs, where I am dealing
with modeless. BUT, for modal dialogs, you can't click 'x' to shut
down the app, since you can't get focus to it to do so. So, in that
case, like for MessageBox.Show(), there is no issue, as the dialog
must close before you continue.

So, the only real issue is for modeless dialogs, and perhaps you have
not dealt with these (in the manner we've be speaking about), and this
is the source of confusion? modal != modeless?
Again, I think you mean modeless dialogs. Understood.

I don't mean modeless dialog. A modeless dialog (or form) is just a form
that has been shown using Show rather than ShowDialog.
Ah, so that's how you make them different. I'll try testing the
differences between modal and modeless now. Although, hm, it doesn't
matter, modal keeps the focus, and by definition, there's no issue,
you can't close the app if a dialog has focus and won't let it go. So
it really doesn't matter what would happen if the app closed with a
modal open, since it just shouldn't happen under normal circumstances.
Yes, with both modal and modeless dialogs (forms) the resources are
disposed of when the form is closed. The difference is that with a modal
dialog (form), the form is not actually closed at the point in time that
it visually appears to be closed. The actual closing doesn't happen until
later.
Ok, I am having a serious issue with this. A modal dialog, one that
keeps focus until it is closed, is not actually closed when it
visually disappears. But, I have a modeless dialog doing the same
thing (displaying data in it that remains, as proof). So, neither
actually closes when it visually disappears. So, what happens when I
click 'x' on a message box, from MessageBox()? It must actually close
sometime, since I'll never reference it again. They must close when
the reference goes out of scope? That would explain the difference in
FormClosed being called for one of my modeless and not the other,
since the scope of one is the lifetime of the main form, and the scope
of the other is just a button handler.

Thanks for your help, Pete

Zytan

Mar 31 '07 #6

P: n/a
Use FormClosing on the dialog. Modal dialogs are hidden, not closed.
>
I think you mean modeless dialogs. Modal dialogs are closed.

No, they are not. From MSDN: "When a form is displayed as a modal dialog
box, clicking the Close button (the button with an X at the upper-right
corner of the form) causes the form to be hidden and the DialogResult
property to be set to DialogResult.Cancel."

http://msdn2.microsoft.com/en-us/lib...rmclosing.aspx
I am confused. It continues to say: "When the Close method is called
on a Form displayed as a modeless window, you cannot call the Show
method to make the form visible, because the form's resources have
already been released."

But, what's the difference? Both modal and modeless can exist always
and just be hidden away when not in use. The only real difference is
that one steals focus and doesn't let it go, where as the other
doesn't. So, what does that have to do with the way they are handled
when you call Close()?
My About dialog does run FormClosing and FormClosed, and it must be
constructed again if I want to make it appear again.

But how do you display it? Modally or modeless? Do you keep the
reference to the form?
1. My main form has a reference to a second form for the entire time.
When I call Close() on this second form, it just goes hidden (calls
FormClosing), but it remains. I can make it come back with Show().

2. I have an About form that only has a reference inside of an event
handler for the 'about' button. When I call Close() on it, it calls
FormClosing then FormClosed.

They are both modeless (they don't steal focus and keep it). So, it
must be the reference to the 'second form' that keeps it from call
FormClosed. Since, for the about form, its reference goes away when
the 'about' button' event handler returns.
So FormClosing happens when the modeless dialog is made invisible by
Hide(). I've confirmed that.

It also happens when the modeless dialog is "closed" (but not actually
closed).
Yes.
It just doesn't make sense, though.
Why does FormClosing happen when the dialog is NOT being closed?

Because that's where the dialog result is set. See link above.
http://msdn2.microsoft.com/en-us/lib...logresult.aspx
"The dialog result of a form is the value that is returned from the
form when it is displayed as a modal dialog box."

Ok, that makes sense, it's like the result you get from calling
MessageBox.Show(). That's a modal dialog.

In both of my cases, the dialogs are modeless (although the about box
really should be modal).
And, when the dialog is eventually shut down by the application
terminated (which I'd like to know how, and when) why doesn't both
FormClosing and FormClosed get run?

Because FormClosing has already been run.
(To be sure we're on the same page, I'm talking about my modeless
dialogs, here, which may or may not be different from modal.) I have
a Debug.WriteLine for both FormClosing and FormClosing, and I would
see if either is run at all, ever, and neither is run. In this case,
I make the dialog appear, and close the whole app:

DialogForm constructing. <-- it only constructs
MainForm constructing.
MainForm closing.
MainForm closed.

But, it is run, if I click 'x' to close it, or my Hide button that
calls Hide(). In this case, I repeatedly make it appear, and close
it:

DialogForm constructing.
MainForm constructing.
DialogForm closing. <-- me clicking 'x'
DialogForm closing. <-- me calling Hide(), after making it appear
again
DialogForm closing. <-- and so on.
MainForm closing.
MainForm closed.

So, FormClosing is only for, for my modeless dialog, when I call
Hide() or press 'x'. It has a reference to it in the MainForm (as you
can see, since even it is constructed before the MainForm is!)
FormClosing is the only one of
the two that is EVER run, and it only runs on Hide(), not when the app
shuts down.

It should run any time the modal dialog is dismissed (whether by Hide() or
clicking the close button or whatever).
Yes, it is.
If your application terminates normally, which means it waits until all
forms are closed, then you should get the FormClosed event for all the
forms.
Pressing 'x' on the main form terminates the app, and for all modeless
dialogs that are open, they do not get FormClosing or FormClosed. I
can verify this by calling MessageBox.Show or Debug.WriteLine in these
events. So, is pressing 'x' a 'normal termination'? Or should I
'catch' this, and instruct all forms to close?
If your application does not terminate normally, then lots of
things are prevented from executing, and I'm not surprised the FormClosed
event is one of those things.
Please define "not terminating normally". Maybe this is my issue.
If it's not working like that, then I have no explanation. I'm not an
expert in how the underlying forms stuff works. I just know what I've
done and what the docs say.
I think maybe you're dealing with modal dialogs, where I am dealing
with modeless. BUT, for modal dialogs, you can't click 'x' to shut
down the app, since you can't get focus to it to do so. So, in that
case, like for MessageBox.Show(), there is no issue, as the dialog
must close before you continue.

So, the only real issue is for modeless dialogs, and perhaps you have
not dealt with these (in the manner we've be speaking about), and this
is the source of confusion? modal != modeless?
Again, I think you mean modeless dialogs. Understood.

I don't mean modeless dialog. A modeless dialog (or form) is just a form
that has been shown using Show rather than ShowDialog.
Ah, so that's how you make them different. I'll try testing the
differences between modal and modeless now. Although, hm, it doesn't
matter, modal keeps the focus, and by definition, there's no issue,
you can't close the app if a dialog has focus and won't let it go. So
it really doesn't matter what would happen if the app closed with a
modal open, since it just shouldn't happen under normal circumstances.
Yes, with both modal and modeless dialogs (forms) the resources are
disposed of when the form is closed. The difference is that with a modal
dialog (form), the form is not actually closed at the point in time that
it visually appears to be closed. The actual closing doesn't happen until
later.
Ok, I am having a serious issue with this. A modal dialog, one that
keeps focus until it is closed, is not actually closed when it
visually disappears. But, I have a modeless dialog doing the same
thing (displaying data in it that remains, as proof). So, neither
actually closes when it visually disappears. So, what happens when I
click 'x' on a message box, from MessageBox()? It must actually close
sometime, since I'll never reference it again. They must close when
the reference goes out of scope? That would explain the difference in
FormClosed being called for one of my modeless and not the other,
since the scope of one is the lifetime of the main form, and the scope
of the other is just a button handler.

Thanks for your help, Pete

Zytan

Mar 31 '07 #7

P: n/a
But how do you display it? Modally or modeless? Do you keep the
reference to the form?

1. My main form has a reference to a second form for the entire time.
When I call Close() on this second form, it just goes hidden (calls
FormClosing), but it remains. I can make it come back with Show().

2. I have an About form that only has a reference inside of an event
handler for the 'about' button. When I call Close() on it, it calls
FormClosing then FormClosed.

They are both modeless (they don't steal focus and keep it). So, it
must be the reference to the 'second form' that keeps it from call
FormClosed. Since, for the about form, its reference goes away when
the 'about' button' event handler returns.
Ok, I tried make a reference to the form in the mainform, instead of
this:

private DialogForm1 m_dialog1 = new DialogForm1();

I do this:

private DialogForm2 m_dialog2;

Both are class data members. But, in the 2nd case, where I must
eventually construct this object, when I call Close() on it, it DOES
call FormClosing then FormClosed. But, on the 1st one, when I call
Close(), it acts as if I just called Hide(), and calls FormClosing,
but it still exists. I know it still exists, since I can call Show()
on it. For the 2nd one, it is actually disposed, and I cannot Show()
it again.

So, same reference, but they are initialized in different locations.
I am willing to bet you choose the 2nd method, since it corresponds
with what you've said should happen. But, why does it have a
different result than this first method (which some tutorial told me
about, which mentioned NOTHING about how to close the darn thing)?

Zytan

Mar 31 '07 #8

P: n/a
On Sat, 31 Mar 2007 12:53:36 -0700, Zytan <zy**********@gmail.comwrote:
[...]
Both are class data members. But, in the 2nd case, where I must
eventually construct this object, when I call Close() on it, it DOES
call FormClosing then FormClosed. But, on the 1st one, when I call
Close(), it acts as if I just called Hide(), and calls FormClosing,
but it still exists. I know it still exists, since I can call Show()
on it. For the 2nd one, it is actually disposed, and I cannot Show()
it again.
I believe that what is happening is related to the order in which the
forms are created. My statement about the application terminating
normally when all the forms have been closed is misleading; what I really
mean is that normally you create a main form, and the rest of the
application propogates from that. You created a situation in which you
are creating a secondary form before you've actually created the main form
(that is, you have an instance but InitializeComponent hasn't been called
yet), and so closing the main form simply results in exiting the
application rather than disposing the forms that were created.

I don't have a justification for this behavior (it seems to me that .NET
could do a better job of tracking open forms and providing more consistent
behavior). It just seems to be the explanation for what's going on.

And of course, it makes sense that the resources used by an object would
not be disposed of until the object itself has been released (or
explicitly disposed, but that's not going on here). That's normal .NET
behavior. Thus, when you retain a reference to a form, it sticks around
able to be shown or hidden at will. If you do not, then when the form is
finally done and there are no more references, it's disposed of and
deleted.

Pete
Mar 31 '07 #9

P: n/a
I believe that what is happening is related to the order in which the
forms are created. My statement about the application terminating
normally when all the forms have been closed is misleading; what I really
mean is that normally you create a main form, and the rest of the
application propogates from that. You created a situation in which you
are creating a secondary form before you've actually created the main form
(that is, you have an instance but InitializeComponent hasn't been called
yet), and so closing the main form simply results in exiting the
application rather than disposing the forms that were created.
Right, that makes sense. I have no idea why that tutorial recommended
the creation of the form after the main form. From the
Debug.WriteLine, I can see that the form is constructed before the
main form. That just can't be good.
I don't have a justification for this behavior (it seems to me that .NET
could do a better job of tracking open forms and providing more consistent
behavior). It just seems to be the explanation for what's going on.
Yes, it'd be nice even if the debugger stepped in, like it does with
cross-threading calls, and says, "Hey, this isn't the right way to do
thins." I bet lots of people are doing it this way, and because it
seems to work, they are happy.
And of course, it makes sense that the resources used by an object would
not be disposed of until the object itself has been released (or
explicitly disposed, but that's not going on here). That's normal .NET
behavior. Thus, when you retain a reference to a form, it sticks around
able to be shown or hidden at will. If you do not, then when the form is
finally done and there are no more references, it's disposed of and
deleted.
Right.

Thanks for all your help, Pete!

Ok, one last question: Modal dialogs are easy, since they maintain
focus and can be constructed / disposed in one block of code. So,
only modeless dialogs are difficult. How do you create / handle your
modeless dialogs? Do you keep them around and just hide them? That
seems easy. Or do you construct / destruct as needed? That seems
more difficult, since, by their nature, they are modeless, so the
logic cannot be constrained to one block of code.

Zytan

Apr 1 '07 #10

P: n/a
On Sun, 01 Apr 2007 11:22:14 -0700, Zytan <zy**********@gmail.comwrote:
[...]
Ok, one last question: Modal dialogs are easy, since they maintain
focus and can be constructed / disposed in one block of code. So,
only modeless dialogs are difficult. How do you create / handle your
modeless dialogs? Do you keep them around and just hide them? That
seems easy. Or do you construct / destruct as needed? That seems
more difficult, since, by their nature, they are modeless, so the
logic cannot be constrained to one block of code.
I'm not really sure what you mean. Whether a form is displayed as modal
or modeless, the code that operates the form is (presumably) contained
with the form's class. It's not in a single block but it is within the
class.

It sounds as though you are instead asking about the code that
instantiates the form. It's true that because of the way a modal dialog
is used, the code almost always instantiates it within the same block of
code that will display it, but there's no requirement that you do so.

I don't find managing the instantiation and destruction of form instances
to be difficult in any case. In many cases (most?) I don't even need a
reference to the form itself, because the form is self-contained. The
form represents the user interface for whatever data or operations the
user is managing through that form, and all of the code is within the form
class. In the cases where some other code needs to interact with the
form, it is almost always the case that I'm dealing with a different class
that I can just pass the form reference to for it to keep track of as long
as it needs to (note that the other class doesn't manage the form...it
just uses that reference to communicate processing information to).

Finally, in the rare case where some code outside the form is responsible
for how the form is displayed and maintained, it's simple enough to keep a
reference to the form with that code.

It's hard to answer your question, because there are so many different
reasons one might display a form (modal or modeless) and different
scenarios require different ways of managing the form and its interaction
with other code (including other forms). But regardless of the scenario,
where to keep references to forms and when to instantiate and destroy them
isn't something I've found difficult to deal with.

Pete
Apr 1 '07 #11

P: n/a
It's hard to answer your question, because there are so many different
reasons one might display a form (modal or modeless) and different
scenarios require different ways of managing the form and its interaction
with other code (including otherforms). But regardless of the scenario,
where to keep references toformsand when to instantiate and destroy them
isn't something I've found difficult to deal with.
Thanks for trying, Pete, your replies help. I think I can only answer
my issues when I try and do what I want to do, instead of following
bad advice from tutorials that gave no real reasons for the way they
do thing, and thus no way to really learn why it is the way it is.

Zytan

Apr 12 '07 #12

This discussion thread is closed

Replies have been disabled for this discussion.