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

Weird Problem: Closing MDI Parent re-directed to MDI Child

P: n/a
For some reason, when I click the X to close my MDI parent form, the action
appears to be re-directed to one of the MDI child forms, and the parent
remains open. I am then unable to close the application.

What should happen, is that the main MDI form should close, taking the child
forms with it. There is code to loop through the child forms, remove the
controls on each of them, and then close the form, but this code should
execute only when the user clicks a specific menu option.

What actually happens is when I click the X to close the main form, the
first of the child forms has all its controls removed, and nothing else
happens.

I realise that I haven't given much to go on, but I just wondered if anyone
had any thoughts/suggestions of what could cause this.

TIA

Charles
Nov 20 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Hi,

Sorry I haven't been able to reproduce that behavior. Is it possible
you have code in forms closing event preventing the app from closing
properly?

Ken
-----------------

"Charles Law" <bl***@nowhere.com> wrote in message
news:Oh**************@TK2MSFTNGP09.phx.gbl:
For some reason, when I click the X to close my MDI parent form, the
action
appears to be re-directed to one of the MDI child forms, and the parent
remains open. I am then unable to close the application.

What should happen, is that the main MDI form should close, taking the
child
forms with it. There is code to loop through the child forms, remove the

controls on each of them, and then close the form, but this code should
execute only when the user clicks a specific menu option.

What actually happens is when I click the X to close the main form, the
first of the child forms has all its controls removed, and nothing else
happens.

I realise that I haven't given much to go on, but I just wondered if
anyone
had any thoughts/suggestions of what could cause this.

TIA

Charles


--
Outgoing mail is certified Virus Free.
Checked by AVG Anti-Virus (http://www.grisoft.com).
Version: 7.0.230 / Virus Database: 263.1.2 - Release Date: 6/7/2004
Nov 20 '05 #2

P: n/a
Hi Ken

The exact procedure that causes this effect is

Start main app
Open MDI child form
Close MDI child form
Open MDI child form
Click X to close main app

The last step, in this scenario, now causes the currently open MDI child
form to clear its controls and nothing else. If I were to click the X after
the first open then all would be well.

I have an event handler in the main MDI parent form, with 'Handles
MyBase.Closed', but this is never called after following the steps above (it
is called if I click the X after the first open).

What could be going on?

Charles
"Ken Tucker [MVP]" <vb***@bellsouth.net> wrote in message
news:eV**************@TK2MSFTNGP11.phx.gbl...
Hi,

Sorry I haven't been able to reproduce that behavior. Is it possible
you have code in forms closing event preventing the app from closing
properly?

Ken
-----------------

"Charles Law" <bl***@nowhere.com> wrote in message
news:Oh**************@TK2MSFTNGP09.phx.gbl:
For some reason, when I click the X to close my MDI parent form, the
action
appears to be re-directed to one of the MDI child forms, and the parent
remains open. I am then unable to close the application.

What should happen, is that the main MDI form should close, taking the
child
forms with it. There is code to loop through the child forms, remove the

controls on each of them, and then close the form, but this code should
execute only when the user clicks a specific menu option.

What actually happens is when I click the X to close the main form, the
first of the child forms has all its controls removed, and nothing else
happens.

I realise that I haven't given much to go on, but I just wondered if
anyone
had any thoughts/suggestions of what could cause this.

TIA

Charles


--
Outgoing mail is certified Virus Free.
Checked by AVG Anti-Virus (http://www.grisoft.com).
Version: 7.0.230 / Virus Database: 263.1.2 - Release Date: 6/7/2004

Nov 20 '05 #3

P: n/a
Charles,
For some reason, when I click the X to close my MDI parent form, the action appears to be re-directed to one of the MDI child forms, I would expect when you close the MDI parent that it will be re-directed to
all of your MDI child forms! As the MDI parent cannot close until all the
MDI child's are closed.

In other words. MDIParent.Close automatically causes MDIChild.Close!
and the parent
remains open. I am then unable to close the application. Are you canceling the first MDI Child's Form.Closing event?
What should happen, is that the main MDI form should close, taking the child forms with it. This is normal .NET behavior, unless you have an event, such as Closing,
canceling the operation.
There is code to loop through the child forms, remove the
controls on each of them, and then close the form, but this code should
execute only when the user clicks a specific menu option. The Form.Closing & Form.Closed event occurs for MDI child forms whether they
are closed explicitly via code or implicitly via the MDI parent being
closed.
What actually happens is when I click the X to close the main form, the
first of the child forms has all its controls removed, and nothing else
happens. Which event are you removing all the controls in?
Are you handling the Form.Closing & Form.Closed events or did you override
the Form.OnClosing & Form.OnClosed methods. If you overrode OnClosing, did
you remember to call the base methods?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:Oh**************@TK2MSFTNGP09.phx.gbl... For some reason, when I click the X to close my MDI parent form, the action appears to be re-directed to one of the MDI child forms, and the parent
remains open. I am then unable to close the application.

What should happen, is that the main MDI form should close, taking the child forms with it. There is code to loop through the child forms, remove the
controls on each of them, and then close the form, but this code should
execute only when the user clicks a specific menu option.

What actually happens is when I click the X to close the main form, the
first of the child forms has all its controls removed, and nothing else
happens.

I realise that I haven't given much to go on, but I just wondered if anyone had any thoughts/suggestions of what could cause this.

TIA

Charles

Nov 20 '05 #4

P: n/a
Hi Jay

I see now why it goes to the child forms first. I should have thought of
that ;-)

At the MDI form level I handle the Form.Closed event. At the child level, I
have overridden the OnClosing method, the first line of which is
MyBase.OnClosing(e). It is in the OnClosing override that I remove all the
controls from the form.

I have simplified the process for making it behave oddly:

Start MDI form app
Open child form
Close child form
Click X to close app (nothing happens)

whereas

Start MDI form app
Open child form
Click X to close app (closes as normal)

Opening the child form loads some user controls and adds event handlers to
an object on the main form, where methods of the user controls are the
target.

The OnClosing method looks like this

<code>
Protected Overrides Sub OnClosing(ByVal e As
System.ComponentModel.CancelEventArgs)

MyBase.OnClosing(e)

' When the form closes, remove all controls from the Controls list
and
' dispose them first
m_SelectedControls.Clear()

' First copy the controls to the selected list, to avoid
' modifying the later loop whilst it is executing
m_SelectedControls.AddRange(Controls)

For Each ctl As Control In m_SelectedControls
Controls.Remove(ctl)

ctl.Dispose()
Next ctl

End Sub
</code>

This removes the controls prior to the form closing.

Does any of this make it clearer?

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:eq**************@TK2MSFTNGP10.phx.gbl...
Charles,
For some reason, when I click the X to close my MDI parent form, the action
appears to be re-directed to one of the MDI child forms,

I would expect when you close the MDI parent that it will be re-directed

to all of your MDI child forms! As the MDI parent cannot close until all the
MDI child's are closed.

In other words. MDIParent.Close automatically causes MDIChild.Close!
and the parent
remains open. I am then unable to close the application. Are you canceling the first MDI Child's Form.Closing event?
What should happen, is that the main MDI form should close, taking the

child
forms with it.

This is normal .NET behavior, unless you have an event, such as Closing,
canceling the operation.
There is code to loop through the child forms, remove the
controls on each of them, and then close the form, but this code should
execute only when the user clicks a specific menu option.

The Form.Closing & Form.Closed event occurs for MDI child forms whether

they are closed explicitly via code or implicitly via the MDI parent being
closed.
What actually happens is when I click the X to close the main form, the
first of the child forms has all its controls removed, and nothing else
happens.

Which event are you removing all the controls in?
Are you handling the Form.Closing & Form.Closed events or did you override
the Form.OnClosing & Form.OnClosed methods. If you overrode OnClosing, did
you remember to call the base methods?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:Oh**************@TK2MSFTNGP09.phx.gbl...
For some reason, when I click the X to close my MDI parent form, the

action
appears to be re-directed to one of the MDI child forms, and the parent
remains open. I am then unable to close the application.

What should happen, is that the main MDI form should close, taking the

child
forms with it. There is code to loop through the child forms, remove the
controls on each of them, and then close the form, but this code should
execute only when the user clicks a specific menu option.

What actually happens is when I click the X to close the main form, the
first of the child forms has all its controls removed, and nothing else
happens.

I realise that I haven't given much to go on, but I just wondered if

anyone
had any thoughts/suggestions of what could cause this.

TIA

Charles


Nov 20 '05 #5

P: n/a
Charles,
This removes the controls prior to the form closing.

Does any of this make it clearer? What is not clear is why you are removing the controls the explicitly? The
Form class will implicitly remove the controls for you.

Does one of your controls or another handler of the Closing event cancel the
Closing event?

Is this VS.NET 2002 or VS.NET 2003?

As Ken suggested, I am not able to recreate this behavior, even with
explicitly removing the controls...

What type of collection is m_SelectedControls?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:uj**************@TK2MSFTNGP10.phx.gbl... Hi Jay

I see now why it goes to the child forms first. I should have thought of
that ;-)

At the MDI form level I handle the Form.Closed event. At the child level, I have overridden the OnClosing method, the first line of which is
MyBase.OnClosing(e). It is in the OnClosing override that I remove all the
controls from the form.

I have simplified the process for making it behave oddly:

Start MDI form app
Open child form
Close child form
Click X to close app (nothing happens)

whereas

Start MDI form app
Open child form
Click X to close app (closes as normal)

Opening the child form loads some user controls and adds event handlers to
an object on the main form, where methods of the user controls are the
target.

The OnClosing method looks like this

<code>
Protected Overrides Sub OnClosing(ByVal e As
System.ComponentModel.CancelEventArgs)

MyBase.OnClosing(e)

' When the form closes, remove all controls from the Controls list
and
' dispose them first
m_SelectedControls.Clear()

' First copy the controls to the selected list, to avoid
' modifying the later loop whilst it is executing
m_SelectedControls.AddRange(Controls)

For Each ctl As Control In m_SelectedControls
Controls.Remove(ctl)

ctl.Dispose()
Next ctl

End Sub
</code>

This removes the controls prior to the form closing.

Does any of this make it clearer?

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:eq**************@TK2MSFTNGP10.phx.gbl...
Charles,
For some reason, when I click the X to close my MDI parent form, the

action
appears to be re-directed to one of the MDI child forms,

I would expect when you close the MDI parent that it will be re-directed

to
all of your MDI child forms! As the MDI parent cannot close until all the MDI child's are closed.

In other words. MDIParent.Close automatically causes MDIChild.Close!
and the parent
remains open. I am then unable to close the application.

Are you canceling the first MDI Child's Form.Closing event?
What should happen, is that the main MDI form should close, taking the

child
forms with it.

This is normal .NET behavior, unless you have an event, such as Closing,
canceling the operation.
There is code to loop through the child forms, remove the
controls on each of them, and then close the form, but this code should execute only when the user clicks a specific menu option.

The Form.Closing & Form.Closed event occurs for MDI child forms whether

they
are closed explicitly via code or implicitly via the MDI parent being
closed.
What actually happens is when I click the X to close the main form, the first of the child forms has all its controls removed, and nothing else happens.

Which event are you removing all the controls in?
Are you handling the Form.Closing & Form.Closed events or did you override the Form.OnClosing & Form.OnClosed methods. If you overrode OnClosing, did you remember to call the base methods?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:Oh**************@TK2MSFTNGP09.phx.gbl...
For some reason, when I click the X to close my MDI parent form, the

action
appears to be re-directed to one of the MDI child forms, and the parent remains open. I am then unable to close the application.

What should happen, is that the main MDI form should close, taking the

child
forms with it. There is code to loop through the child forms, remove the controls on each of them, and then close the form, but this code should execute only when the user clicks a specific menu option.

What actually happens is when I click the X to close the main form, the first of the child forms has all its controls removed, and nothing else happens.

I realise that I haven't given much to go on, but I just wondered if

anyone
had any thoughts/suggestions of what could cause this.

TIA

Charles



Nov 20 '05 #6

P: n/a
Hi Jay

m_SelectedControls is an ArrayList, and I am using VS 2003.

I'm removing the controls explicitly because they are user controls that
sink events, and ultimately, I know that as part of this process I must
unhook the handlers from the events. This is part of problem 2 (of 3), that
if I close a child form that is servicing events, without unhooking the
handlers, then when the event is next raised it still calls the code in the
old handler, and if the object that was the target of the handler has been
disposed an exception is thrown to the effect that I cannot access a control
that has been disposed.
Does one of your controls or another handler of the Closing event cancel the Closing event?
None of my controls or handlers attempt to cancel the Closing event.

With regard to reproducing the behaviour, I wonder if the fact that the
controls sink events is significant. If I do the same thing w/o adding
controls to the form then all is well.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl... Charles,
This removes the controls prior to the form closing.

Does any of this make it clearer? What is not clear is why you are removing the controls the explicitly? The
Form class will implicitly remove the controls for you.

Does one of your controls or another handler of the Closing event cancel

the Closing event?

Is this VS.NET 2002 or VS.NET 2003?

As Ken suggested, I am not able to recreate this behavior, even with
explicitly removing the controls...

What type of collection is m_SelectedControls?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:uj**************@TK2MSFTNGP10.phx.gbl...
Hi Jay

I see now why it goes to the child forms first. I should have thought of
that ;-)

At the MDI form level I handle the Form.Closed event. At the child level,
I
have overridden the OnClosing method, the first line of which is
MyBase.OnClosing(e). It is in the OnClosing override that I remove all the controls from the form.

I have simplified the process for making it behave oddly:

Start MDI form app
Open child form
Close child form
Click X to close app (nothing happens)

whereas

Start MDI form app
Open child form
Click X to close app (closes as normal)

Opening the child form loads some user controls and adds event handlers to an object on the main form, where methods of the user controls are the
target.

The OnClosing method looks like this

<code>
Protected Overrides Sub OnClosing(ByVal e As
System.ComponentModel.CancelEventArgs)

MyBase.OnClosing(e)

' When the form closes, remove all controls from the Controls list and
' dispose them first
m_SelectedControls.Clear()

' First copy the controls to the selected list, to avoid
' modifying the later loop whilst it is executing
m_SelectedControls.AddRange(Controls)

For Each ctl As Control In m_SelectedControls
Controls.Remove(ctl)

ctl.Dispose()
Next ctl

End Sub
</code>

This removes the controls prior to the form closing.

Does any of this make it clearer?

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:eq**************@TK2MSFTNGP10.phx.gbl...
Charles,
> For some reason, when I click the X to close my MDI parent form, the
action
> appears to be re-directed to one of the MDI child forms,
I would expect when you close the MDI parent that it will be re-directed
to
all of your MDI child forms! As the MDI parent cannot close until all the MDI child's are closed.

In other words. MDIParent.Close automatically causes MDIChild.Close!

> and the parent
> remains open. I am then unable to close the application.
Are you canceling the first MDI Child's Form.Closing event?

> What should happen, is that the main MDI form should close, taking
the child
> forms with it.
This is normal .NET behavior, unless you have an event, such as Closing, canceling the operation.

> There is code to loop through the child forms, remove the
> controls on each of them, and then close the form, but this code

should > execute only when the user clicks a specific menu option.
The Form.Closing & Form.Closed event occurs for MDI child forms whether they
are closed explicitly via code or implicitly via the MDI parent being
closed.

> What actually happens is when I click the X to close the main form, the > first of the child forms has all its controls removed, and nothing else > happens.
Which event are you removing all the controls in?
Are you handling the Form.Closing & Form.Closed events or did you override the Form.OnClosing & Form.OnClosed methods. If you overrode OnClosing, did you remember to call the base methods?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:Oh**************@TK2MSFTNGP09.phx.gbl...
> For some reason, when I click the X to close my MDI parent form, the
action
> appears to be re-directed to one of the MDI child forms, and the parent > remains open. I am then unable to close the application.
>
> What should happen, is that the main MDI form should close, taking
the child
> forms with it. There is code to loop through the child forms, remove

the > controls on each of them, and then close the form, but this code should > execute only when the user clicks a specific menu option.
>
> What actually happens is when I click the X to close the main form, the > first of the child forms has all its controls removed, and nothing else > happens.
>
> I realise that I haven't given much to go on, but I just wondered if
anyone
> had any thoughts/suggestions of what could cause this.
>
> TIA
>
> Charles
>
>



Nov 20 '05 #7

P: n/a
Charles,
I'm removing the controls explicitly because they are user controls that
sink events, and ultimately, I know that as part of this process I must
unhook the handlers from the events. I would not remove the controls explicitly to unhook the handlers, I would
simply assign Nothing to the UserControl's SelectedObject property, where
the SelectedObject property unhooks the existing handler. Where the
SelectedObject property is a property of the correct name & type for the
type of "domain object" the user control displays. For example if I have a
Person object and a PersonControl that displays a Person object. The
PersonControl would have a SelectedPerson property. Within the
SelectedPerson property I would remove any handlers of the existing Person
before assigning the handlers for the new object.
With regard to reproducing the behaviour, I wonder if the fact that the
controls sink events is significant. If I do the same thing w/o adding
controls to the form then all is well. I don't have a good test setup right now to test if having a user control
handle an external object's events is messing up the Closing, I would be
surprised if it does.

Did I ask if there are any Exceptions being raised that is causing the
Closing Event to end unexpectedly?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl... Hi Jay

m_SelectedControls is an ArrayList, and I am using VS 2003.

I'm removing the controls explicitly because they are user controls that
sink events, and ultimately, I know that as part of this process I must
unhook the handlers from the events. This is part of problem 2 (of 3), that if I close a child form that is servicing events, without unhooking the
handlers, then when the event is next raised it still calls the code in the old handler, and if the object that was the target of the handler has been
disposed an exception is thrown to the effect that I cannot access a control that has been disposed.
Does one of your controls or another handler of the Closing event cancel the
Closing event?


None of my controls or handlers attempt to cancel the Closing event.

With regard to reproducing the behaviour, I wonder if the fact that the
controls sink events is significant. If I do the same thing w/o adding
controls to the form then all is well.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
Charles,
This removes the controls prior to the form closing.

Does any of this make it clearer?

What is not clear is why you are removing the controls the explicitly? The
Form class will implicitly remove the controls for you.

Does one of your controls or another handler of the Closing event cancel

the
Closing event?

Is this VS.NET 2002 or VS.NET 2003?

As Ken suggested, I am not able to recreate this behavior, even with
explicitly removing the controls...

What type of collection is m_SelectedControls?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:uj**************@TK2MSFTNGP10.phx.gbl...
Hi Jay

I see now why it goes to the child forms first. I should have thought of that ;-)

At the MDI form level I handle the Form.Closed event. At the child level,
I
have overridden the OnClosing method, the first line of which is
MyBase.OnClosing(e). It is in the OnClosing override that I remove all

the controls from the form.

I have simplified the process for making it behave oddly:

Start MDI form app
Open child form
Close child form
Click X to close app (nothing happens)

whereas

Start MDI form app
Open child form
Click X to close app (closes as normal)

Opening the child form loads some user controls and adds event handlers to
an object on the main form, where methods of the user controls are the
target.

The OnClosing method looks like this

<code>
Protected Overrides Sub OnClosing(ByVal e As
System.ComponentModel.CancelEventArgs)

MyBase.OnClosing(e)

' When the form closes, remove all controls from the Controls list and
' dispose them first
m_SelectedControls.Clear()

' First copy the controls to the selected list, to avoid
' modifying the later loop whilst it is executing
m_SelectedControls.AddRange(Controls)

For Each ctl As Control In m_SelectedControls
Controls.Remove(ctl)

ctl.Dispose()
Next ctl

End Sub
</code>

This removes the controls prior to the form closing.

Does any of this make it clearer?

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:eq**************@TK2MSFTNGP10.phx.gbl...
> Charles,
> > For some reason, when I click the X to close my MDI parent form,
the > action
> > appears to be re-directed to one of the MDI child forms,
> I would expect when you close the MDI parent that it will be

re-directed to
> all of your MDI child forms! As the MDI parent cannot close until all the
> MDI child's are closed.
>
> In other words. MDIParent.Close automatically causes MDIChild.Close!
>
> > and the parent
> > remains open. I am then unable to close the application.
> Are you canceling the first MDI Child's Form.Closing event?
>
> > What should happen, is that the main MDI form should close, taking the > child
> > forms with it.
> This is normal .NET behavior, unless you have an event, such as Closing, > canceling the operation.
>
> > There is code to loop through the child forms, remove the
> > controls on each of them, and then close the form, but this code

should
> > execute only when the user clicks a specific menu option.
> The Form.Closing & Form.Closed event occurs for MDI child forms whether they
> are closed explicitly via code or implicitly via the MDI parent
being > closed.
>
> > What actually happens is when I click the X to close the main form,
the
> > first of the child forms has all its controls removed, and nothing

else
> > happens.
> Which event are you removing all the controls in?
>
>
> Are you handling the Form.Closing & Form.Closed events or did you

override
> the Form.OnClosing & Form.OnClosed methods. If you overrode
OnClosing, did
> you remember to call the base methods?
>
> Hope this helps
> Jay
>
> "Charles Law" <bl***@nowhere.com> wrote in message
> news:Oh**************@TK2MSFTNGP09.phx.gbl...
> > For some reason, when I click the X to close my MDI parent form,
the > action
> > appears to be re-directed to one of the MDI child forms, and the

parent
> > remains open. I am then unable to close the application.
> >
> > What should happen, is that the main MDI form should close, taking

the > child
> > forms with it. There is code to loop through the child forms, remove the
> > controls on each of them, and then close the form, but this code

should
> > execute only when the user clicks a specific menu option.
> >
> > What actually happens is when I click the X to close the main
form, the
> > first of the child forms has all its controls removed, and nothing

else
> > happens.
> >
> > I realise that I haven't given much to go on, but I just wondered

if > anyone
> > had any thoughts/suggestions of what could cause this.
> >
> > TIA
> >
> > Charles
> >
> >
>
>



Nov 20 '05 #8

P: n/a
Jay

I'm not sure I follow you when you talk about a SelectedObject.

If I can translate your example into my own, let's say I have a Device
object and a ShowStuff object. The ShowStuff object displays information
about the Device object, but knows nothing of the Device object per se [as I
am writing this I think a light is coming on]. As such, the handlers are
attached outside the ShowStuff and Device objects, so the ShowStuff object
does not know what events it is servicing and cannot therefore call
RemoveHandler. I should clarify that I am not removing the objects manually
in order to detach the handlers, as I realise that this does not work; it
was just a precursor to implementing this process.

If I had a SelectedObject property, what would it contain that could remove
the handlers w/o knowing which events had been attached? This question is
actually the subject of another post: 'How to iterate through a list of
sender events and detach all receiver handlers when given only the sender
and receiver as Objects'.

As you say, though, the fact that the handlers are not being detached is
probably not the cause of the app not closing.

I have just traced through the app again, and there are two ways that the
child form can be created:

Case 1.
a. User clicks toolbar button to create new, blank child form
b. User drags usercontrol onto form from toolbox

Case 2.
a. User selects file from open file dialog
b. File is opened and child form is recreated from file (xml)

In case 1, I can close the child form and close the app as normal. In case
2, I can close the child form but the app won't close. However, I cannot see
that the two methods are doing anything substantially different. The same
utility functions for creating the form and instantiating the usercontrol
are used in both cases.

Did I ask if there are any Exceptions being raised that is causing the
Closing Event to end unexpectedly?
I don't think you did, but anyway, there aren't any exceptions thrown. I
have all exceptions set to break into the debugger when they are thrown.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:uS*************@TK2MSFTNGP10.phx.gbl... Charles,
I'm removing the controls explicitly because they are user controls that
sink events, and ultimately, I know that as part of this process I must
unhook the handlers from the events. I would not remove the controls explicitly to unhook the handlers, I would
simply assign Nothing to the UserControl's SelectedObject property, where
the SelectedObject property unhooks the existing handler. Where the
SelectedObject property is a property of the correct name & type for the
type of "domain object" the user control displays. For example if I have a
Person object and a PersonControl that displays a Person object. The
PersonControl would have a SelectedPerson property. Within the
SelectedPerson property I would remove any handlers of the existing Person
before assigning the handlers for the new object.
With regard to reproducing the behaviour, I wonder if the fact that the
controls sink events is significant. If I do the same thing w/o adding
controls to the form then all is well.

I don't have a good test setup right now to test if having a user control
handle an external object's events is messing up the Closing, I would be
surprised if it does.

Did I ask if there are any Exceptions being raised that is causing the
Closing Event to end unexpectedly?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
Hi Jay

m_SelectedControls is an ArrayList, and I am using VS 2003.

I'm removing the controls explicitly because they are user controls that
sink events, and ultimately, I know that as part of this process I must
unhook the handlers from the events. This is part of problem 2 (of 3),

that
if I close a child form that is servicing events, without unhooking the
handlers, then when the event is next raised it still calls the code in

the
old handler, and if the object that was the target of the handler has been
disposed an exception is thrown to the effect that I cannot access a

control
that has been disposed.
Does one of your controls or another handler of the Closing event cancel
the
Closing event?


None of my controls or handlers attempt to cancel the Closing event.

With regard to reproducing the behaviour, I wonder if the fact that the
controls sink events is significant. If I do the same thing w/o adding
controls to the form then all is well.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:%2****************@TK2MSFTNGP10.phx.gbl...
Charles,
> This removes the controls prior to the form closing.
>
> Does any of this make it clearer?
What is not clear is why you are removing the controls the explicitly? The Form class will implicitly remove the controls for you.

Does one of your controls or another handler of the Closing event
cancel the
Closing event?

Is this VS.NET 2002 or VS.NET 2003?

As Ken suggested, I am not able to recreate this behavior, even with
explicitly removing the controls...

What type of collection is m_SelectedControls?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:uj**************@TK2MSFTNGP10.phx.gbl...
> Hi Jay
>
> I see now why it goes to the child forms first. I should have
thought of > that ;-)
>
> At the MDI form level I handle the Form.Closed event. At the child level,
I
> have overridden the OnClosing method, the first line of which is
> MyBase.OnClosing(e). It is in the OnClosing override that I remove
all the
> controls from the form.
>
> I have simplified the process for making it behave oddly:
>
> Start MDI form app
> Open child form
> Close child form
> Click X to close app (nothing happens)
>
> whereas
>
> Start MDI form app
> Open child form
> Click X to close app (closes as normal)
>
> Opening the child form loads some user controls and adds event handlers
to
> an object on the main form, where methods of the user controls are

the > target.
>
> The OnClosing method looks like this
>
> <code>
> Protected Overrides Sub OnClosing(ByVal e As
> System.ComponentModel.CancelEventArgs)
>
> MyBase.OnClosing(e)
>
> ' When the form closes, remove all controls from the Controls list
> and
> ' dispose them first
> m_SelectedControls.Clear()
>
> ' First copy the controls to the selected list, to avoid
> ' modifying the later loop whilst it is executing
> m_SelectedControls.AddRange(Controls)
>
> For Each ctl As Control In m_SelectedControls
> Controls.Remove(ctl)
>
> ctl.Dispose()
> Next ctl
>
> End Sub
> </code>
>
> This removes the controls prior to the form closing.
>
> Does any of this make it clearer?
>
> Charles
>
>
> "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in

message
> news:eq**************@TK2MSFTNGP10.phx.gbl...
> > Charles,
> > > For some reason, when I click the X to close my MDI parent form, the > > action
> > > appears to be re-directed to one of the MDI child forms,
> > I would expect when you close the MDI parent that it will be

re-directed
> to
> > all of your MDI child forms! As the MDI parent cannot close until all the
> > MDI child's are closed.
> >
> > In other words. MDIParent.Close automatically causes
MDIChild.Close! > >
> > > and the parent
> > > remains open. I am then unable to close the application.
> > Are you canceling the first MDI Child's Form.Closing event?
> >
> > > What should happen, is that the main MDI form should close, taking the
> > child
> > > forms with it.
> > This is normal .NET behavior, unless you have an event, such as

Closing,
> > canceling the operation.
> >
> > > There is code to loop through the child forms, remove the
> > > controls on each of them, and then close the form, but this code
should
> > > execute only when the user clicks a specific menu option.
> > The Form.Closing & Form.Closed event occurs for MDI child forms

whether
> they
> > are closed explicitly via code or implicitly via the MDI parent being > > closed.
> >
> > > What actually happens is when I click the X to close the main form, the
> > > first of the child forms has all its controls removed, and
nothing else
> > > happens.
> > Which event are you removing all the controls in?
> >
> >
> > Are you handling the Form.Closing & Form.Closed events or did you
override
> > the Form.OnClosing & Form.OnClosed methods. If you overrode

OnClosing, did
> > you remember to call the base methods?
> >
> > Hope this helps
> > Jay
> >
> > "Charles Law" <bl***@nowhere.com> wrote in message
> > news:Oh**************@TK2MSFTNGP09.phx.gbl...
> > > For some reason, when I click the X to close my MDI parent form, the > > action
> > > appears to be re-directed to one of the MDI child forms, and the
parent
> > > remains open. I am then unable to close the application.
> > >
> > > What should happen, is that the main MDI form should close, taking the
> > child
> > > forms with it. There is code to loop through the child forms, remove the
> > > controls on each of them, and then close the form, but this code
should
> > > execute only when the user clicks a specific menu option.
> > >
> > > What actually happens is when I click the X to close the main form, the
> > > first of the child forms has all its controls removed, and
nothing else
> > > happens.
> > >
> > > I realise that I haven't given much to go on, but I just

wondered if > > anyone
> > > had any thoughts/suggestions of what could cause this.
> > >
> > > TIA
> > >
> > > Charles
> > >
> > >
> >
> >
>
>



Nov 20 '05 #9

P: n/a
Charles,
One word: Encapsulation!
The ShowStuff object displays information
about the Device object, but knows nothing of the Device object per se If ShowStuff knows nothing about the Device object, how does it know what to
display??

I would expect at the very least that ShowStuff would know about DeviceBase
abstract base (mustinherit) class or the IDevice interface, then
polymorphically be able to display any type of Device (derived class) that
may be able to be given to it. Any events that ShowStuff needed to be
implemented would be part of DeviceBase or IDevice.
As such, the handlers are
attached outside the ShowStuff and Device objects, so the ShowStuff object
does not know what events it is servicing and cannot therefore call
RemoveHandler. Yes I read your other question, Herfried gave you the field you need.
However! I would have recommended encapsulation and have ShowStuff be
responsible for adding & removing any handlers that it owns. If you need to
use the DoStuffEvent to remove the handlers you can use
Delegate.GetInvocationList to get all the handlers on a Delegate, then use a
For Each to remove each one.

Something like (untested):
For Each handler As [Delegate] In DoStuffEvent.GetInvocationList()
[Delegate].Remove(DoStuffEvent, handler)
Next

Again I would only use this as a last resort! As I find it a little
anti-encapsulation, in that the object handling the event might have cleanup
that needs to be done before it stops handling the event, and the above
routine will not give the object handling the event a chance to do this
clean up...

This is especially importing if you show the Device in multiple ShowStuff
user controls at one time, where the user can open & close windows at will,
on the same document...
I should clarify that I am not removing the objects manually
in order to detach the handlers, as I realise that this does not work; it
was just a precursor to implementing this process. I am suggesting that you do!
Case 2.
a. User selects file from open file dialog
b. File is opened and child form is recreated from file (xml)

In case 1, I can close the child form and close the app as normal. In case
2, I can close the child form but the app won't close. However, I cannot see that the two methods are doing anything substantially different. The same
utility functions for creating the form and instantiating the usercontrol
are used in both cases. Sounds like something in your 2b logic. 2b or not 2b that is the question.

Can you describe or show how you are opening the file & creating the child
form?

Hope this helps
Jay


"Charles Law" <bl***@nowhere.com> wrote in message
news:eH*************@tk2msftngp13.phx.gbl... Jay

I'm not sure I follow you when you talk about a SelectedObject.

If I can translate your example into my own, let's say I have a Device
object and a ShowStuff object. The ShowStuff object displays information
about the Device object, but knows nothing of the Device object per se [as I am writing this I think a light is coming on]. As such, the handlers are
attached outside the ShowStuff and Device objects, so the ShowStuff object
does not know what events it is servicing and cannot therefore call
RemoveHandler. I should clarify that I am not removing the objects manually in order to detach the handlers, as I realise that this does not work; it
was just a precursor to implementing this process.

If I had a SelectedObject property, what would it contain that could remove the handlers w/o knowing which events had been attached? This question is
actually the subject of another post: 'How to iterate through a list of
sender events and detach all receiver handlers when given only the sender
and receiver as Objects'.

As you say, though, the fact that the handlers are not being detached is
probably not the cause of the app not closing.

I have just traced through the app again, and there are two ways that the
child form can be created:

Case 1.
a. User clicks toolbar button to create new, blank child form
b. User drags usercontrol onto form from toolbox

Case 2.
a. User selects file from open file dialog
b. File is opened and child form is recreated from file (xml)

In case 1, I can close the child form and close the app as normal. In case
2, I can close the child form but the app won't close. However, I cannot see that the two methods are doing anything substantially different. The same
utility functions for creating the form and instantiating the usercontrol
are used in both cases.

Did I ask if there are any Exceptions being raised that is causing the
Closing Event to end unexpectedly?


I don't think you did, but anyway, there aren't any exceptions thrown. I
have all exceptions set to break into the debugger when they are thrown.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:uS*************@TK2MSFTNGP10.phx.gbl...
Charles,
I'm removing the controls explicitly because they are user controls that sink events, and ultimately, I know that as part of this process I must unhook the handlers from the events.

I would not remove the controls explicitly to unhook the handlers, I would
simply assign Nothing to the UserControl's SelectedObject property, where the SelectedObject property unhooks the existing handler. Where the
SelectedObject property is a property of the correct name & type for the
type of "domain object" the user control displays. For example if I have a Person object and a PersonControl that displays a Person object. The
PersonControl would have a SelectedPerson property. Within the
SelectedPerson property I would remove any handlers of the existing Person before assigning the handlers for the new object.
With regard to reproducing the behaviour, I wonder if the fact that the controls sink events is significant. If I do the same thing w/o adding
controls to the form then all is well.

I don't have a good test setup right now to test if having a user control handle an external object's events is messing up the Closing, I would be
surprised if it does.

Did I ask if there are any Exceptions being raised that is causing the
Closing Event to end unexpectedly?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
Hi Jay

m_SelectedControls is an ArrayList, and I am using VS 2003.

I'm removing the controls explicitly because they are user controls that sink events, and ultimately, I know that as part of this process I must unhook the handlers from the events. This is part of problem 2 (of 3),

that
if I close a child form that is servicing events, without unhooking the handlers, then when the event is next raised it still calls the code in
the
old handler, and if the object that was the target of the handler has been disposed an exception is thrown to the effect that I cannot access a

control
that has been disposed.

> Does one of your controls or another handler of the Closing event cancel the
> Closing event?

None of my controls or handlers attempt to cancel the Closing event.

With regard to reproducing the behaviour, I wonder if the fact that
the controls sink events is significant. If I do the same thing w/o adding
controls to the form then all is well.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in

message news:%2****************@TK2MSFTNGP10.phx.gbl...
> Charles,
> > This removes the controls prior to the form closing.
> >
> > Does any of this make it clearer?
> What is not clear is why you are removing the controls the explicitly? The
> Form class will implicitly remove the controls for you.
>
> Does one of your controls or another handler of the Closing event cancel the
> Closing event?
>
> Is this VS.NET 2002 or VS.NET 2003?
>
> As Ken suggested, I am not able to recreate this behavior, even with
> explicitly removing the controls...
>
> What type of collection is m_SelectedControls?
>
> Hope this helps
> Jay
>
> "Charles Law" <bl***@nowhere.com> wrote in message
> news:uj**************@TK2MSFTNGP10.phx.gbl...
> > Hi Jay
> >
> > I see now why it goes to the child forms first. I should have thought
of
> > that ;-)
> >
> > At the MDI form level I handle the Form.Closed event. At the child
level,
> I
> > have overridden the OnClosing method, the first line of which is
> > MyBase.OnClosing(e). It is in the OnClosing override that I remove all the
> > controls from the form.
> >
> > I have simplified the process for making it behave oddly:
> >
> > Start MDI form app
> > Open child form
> > Close child form
> > Click X to close app (nothing happens)
> >
> > whereas
> >
> > Start MDI form app
> > Open child form
> > Click X to close app (closes as normal)
> >
> > Opening the child form loads some user controls and adds event

handlers
to
> > an object on the main form, where methods of the user controls are the > > target.
> >
> > The OnClosing method looks like this
> >
> > <code>
> > Protected Overrides Sub OnClosing(ByVal e As
> > System.ComponentModel.CancelEventArgs)
> >
> > MyBase.OnClosing(e)
> >
> > ' When the form closes, remove all controls from the Controls list
> > and
> > ' dispose them first
> > m_SelectedControls.Clear()
> >
> > ' First copy the controls to the selected list, to avoid
> > ' modifying the later loop whilst it is executing
> > m_SelectedControls.AddRange(Controls)
> >
> > For Each ctl As Control In m_SelectedControls
> > Controls.Remove(ctl)
> >
> > ctl.Dispose()
> > Next ctl
> >
> > End Sub
> > </code>
> >
> > This removes the controls prior to the form closing.
> >
> > Does any of this make it clearer?
> >
> > Charles
> >
> >
> > "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in
message
> > news:eq**************@TK2MSFTNGP10.phx.gbl...
> > > Charles,
> > > > For some reason, when I click the X to close my MDI parent
form, the
> > > action
> > > > appears to be re-directed to one of the MDI child forms,
> > > I would expect when you close the MDI parent that it will be
re-directed
> > to
> > > all of your MDI child forms! As the MDI parent cannot close
until all
> the
> > > MDI child's are closed.
> > >
> > > In other words. MDIParent.Close automatically causes MDIChild.Close! > > >
> > > > and the parent
> > > > remains open. I am then unable to close the application.
> > > Are you canceling the first MDI Child's Form.Closing event?
> > >
> > > > What should happen, is that the main MDI form should close, taking the
> > > child
> > > > forms with it.
> > > This is normal .NET behavior, unless you have an event, such as
Closing,
> > > canceling the operation.
> > >
> > > > There is code to loop through the child forms, remove the
> > > > controls on each of them, and then close the form, but this
code > should
> > > > execute only when the user clicks a specific menu option.
> > > The Form.Closing & Form.Closed event occurs for MDI child forms
whether
> > they
> > > are closed explicitly via code or implicitly via the MDI parent

being
> > > closed.
> > >
> > > > What actually happens is when I click the X to close the main

form,
> the
> > > > first of the child forms has all its controls removed, and

nothing > else
> > > > happens.
> > > Which event are you removing all the controls in?
> > >
> > >
> > > Are you handling the Form.Closing & Form.Closed events or did you > override
> > > the Form.OnClosing & Form.OnClosed methods. If you overrode

OnClosing,
> did
> > > you remember to call the base methods?
> > >
> > > Hope this helps
> > > Jay
> > >
> > > "Charles Law" <bl***@nowhere.com> wrote in message
> > > news:Oh**************@TK2MSFTNGP09.phx.gbl...
> > > > For some reason, when I click the X to close my MDI parent form, the
> > > action
> > > > appears to be re-directed to one of the MDI child forms, and
the > parent
> > > > remains open. I am then unable to close the application.
> > > >
> > > > What should happen, is that the main MDI form should close,

taking the
> > > child
> > > > forms with it. There is code to loop through the child forms,

remove
> the
> > > > controls on each of them, and then close the form, but this code > should
> > > > execute only when the user clicks a specific menu option.
> > > >
> > > > What actually happens is when I click the X to close the main

form,
> the
> > > > first of the child forms has all its controls removed, and nothing > else
> > > > happens.
> > > >
> > > > I realise that I haven't given much to go on, but I just

wondered
if
> > > anyone
> > > > had any thoughts/suggestions of what could cause this.
> > > >
> > > > TIA
> > > >
> > > > Charles
> > > >
> > > >
> > >
> > >
> >
> >
>
>



Nov 20 '05 #10

P: n/a
Hi Jay
One word: Encapsulation!
That was the little light. As I was describing the scenario I was thinking
'what I ought to have is an interface that defines the Device events that my
ShowStuff object would know about' :-)

The file is opened as follows

<code>
Public Shared Function Read(ByVal filespec As String) As View

Dim fs As FileStream
Dim vw As View

' Creates an instance of the XmlSerializer class;
' specify the type of object to be deserialized
Try
Dim serializer As New XmlSerializer(GetType(View))

' A FileStream is needed to read the XML document
fs = New FileStream(filespec, FileMode.Open)

' Declare an object variable of the type to be deserialized
' Uses the Deserialize method to restore the object's state
with
' data from the XML document
Try
vw = CType(serializer.Deserialize(fs), View)

' View loaded, so update the filepsec
vw.m_Filespec = filespec

Catch ex As Exception
Throw New ConfigException("An error has occurred reading
configuration file " & filespec, ex)

Finally
If Not fs Is Nothing Then
fs.Close()
End If

End Try

Catch ex As FileNotFoundException
Return vw

Catch ex As Exception
Throw New ConfigException("An error has occurred reading
configuration file " & filespec, ex)

End Try

Return vw

End Function
</code>

Any existing forms are closed as follows

<code>
Private Sub CloseView()

' Unload any existing view
For Each frm As Form In MdiChildren
If TypeOf frm Is ItemGroupWindow Then
frm.Close()
End If
Next frm

' Update the current view to point to nothing
m_CurrentView = Nothing

UpdateViewStatus(Nothing)

End Sub
</code>

The forms are created as follows

<code>
For Each ig As ItemGroup In m_CurrentView.ItemGroups
If ig.IsOpen Then
Dim igw As ItemGroupWindow

' Create a new item group window, with the current form as
the MDI parent
igw = New ItemGroupWindow(Me)

With igw
' Set the properties of the new window
.StartPosition = FormStartPosition.Manual
.AutoScroll = True

.WindowState = ig.WindowState.ToFormWindowState
.Size = ig.WindowState.Size
.Location = ig.WindowState.Location
.Text = ig.Title

' Create a new item for each item definition in the item
group
For Each idef As ItemDefinition In ig.Items
Dim dev As DeviceBase

' Get a reference to the specific item from the
device list
dev = DeviceConfig.Devices(idef.Text)

.InstantiateDevice(dev, idef.Location)
Next idef

' Make the new window visible
.Show()

' Scroll the form to the saved position
.AutoScrollPosition = New
Point(-ig.ScrollPosition.X, -ig.ScrollPosition.Y)
End With
End If
Next ig
</code>

The method InstantiateDevice() creates the control defined by the parameters
and attaches handlers appropriate to the type of device created. It is used
whether the form is created manually or from the saved file. In fact, the
saved file is created by manually creating the forms and controls on-screen
and then clicking Save.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:uQ**************@TK2MSFTNGP10.phx.gbl... Charles,
One word: Encapsulation!
The ShowStuff object displays information
about the Device object, but knows nothing of the Device object per se If ShowStuff knows nothing about the Device object, how does it know what

to display??

I would expect at the very least that ShowStuff would know about DeviceBase abstract base (mustinherit) class or the IDevice interface, then
polymorphically be able to display any type of Device (derived class) that
may be able to be given to it. Any events that ShowStuff needed to be
implemented would be part of DeviceBase or IDevice.
As such, the handlers are
attached outside the ShowStuff and Device objects, so the ShowStuff object
does not know what events it is servicing and cannot therefore call
RemoveHandler. Yes I read your other question, Herfried gave you the field you need.
However! I would have recommended encapsulation and have ShowStuff be
responsible for adding & removing any handlers that it owns. If you need

to use the DoStuffEvent to remove the handlers you can use
Delegate.GetInvocationList to get all the handlers on a Delegate, then use a For Each to remove each one.

Something like (untested):
For Each handler As [Delegate] In DoStuffEvent.GetInvocationList()
[Delegate].Remove(DoStuffEvent, handler)
Next

Again I would only use this as a last resort! As I find it a little
anti-encapsulation, in that the object handling the event might have cleanup that needs to be done before it stops handling the event, and the above
routine will not give the object handling the event a chance to do this
clean up...

This is especially importing if you show the Device in multiple ShowStuff
user controls at one time, where the user can open & close windows at will, on the same document...
I should clarify that I am not removing the objects manually
in order to detach the handlers, as I realise that this does not work; it was just a precursor to implementing this process. I am suggesting that you do!
Case 2.
a. User selects file from open file dialog
b. File is opened and child form is recreated from file (xml)

In case 1, I can close the child form and close the app as normal. In case 2, I can close the child form but the app won't close. However, I cannot

see
that the two methods are doing anything substantially different. The same utility functions for creating the form and instantiating the usercontrol are used in both cases.

Sounds like something in your 2b logic. 2b or not 2b that is the question.

Can you describe or show how you are opening the file & creating the child
form?

Hope this helps
Jay


"Charles Law" <bl***@nowhere.com> wrote in message
news:eH*************@tk2msftngp13.phx.gbl...
Jay

I'm not sure I follow you when you talk about a SelectedObject.

If I can translate your example into my own, let's say I have a Device
object and a ShowStuff object. The ShowStuff object displays information
about the Device object, but knows nothing of the Device object per se [as I
am writing this I think a light is coming on]. As such, the handlers are
attached outside the ShowStuff and Device objects, so the ShowStuff
object does not know what events it is servicing and cannot therefore call
RemoveHandler. I should clarify that I am not removing the objects

manually
in order to detach the handlers, as I realise that this does not work; it was just a precursor to implementing this process.

If I had a SelectedObject property, what would it contain that could

remove
the handlers w/o knowing which events had been attached? This question is actually the subject of another post: 'How to iterate through a list of
sender events and detach all receiver handlers when given only the sender and receiver as Objects'.

As you say, though, the fact that the handlers are not being detached is
probably not the cause of the app not closing.

I have just traced through the app again, and there are two ways that the child form can be created:

Case 1.
a. User clicks toolbar button to create new, blank child form
b. User drags usercontrol onto form from toolbox

Case 2.
a. User selects file from open file dialog
b. File is opened and child form is recreated from file (xml)

In case 1, I can close the child form and close the app as normal. In case 2, I can close the child form but the app won't close. However, I cannot

see
that the two methods are doing anything substantially different. The same utility functions for creating the form and instantiating the usercontrol are used in both cases.

Did I ask if there are any Exceptions being raised that is causing the
Closing Event to end unexpectedly?


I don't think you did, but anyway, there aren't any exceptions thrown. I
have all exceptions set to break into the debugger when they are thrown.

Charles
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message news:uS*************@TK2MSFTNGP10.phx.gbl...
Charles,
> I'm removing the controls explicitly because they are user controls that > sink events, and ultimately, I know that as part of this process I must > unhook the handlers from the events.
I would not remove the controls explicitly to unhook the handlers, I would simply assign Nothing to the UserControl's SelectedObject property, where the SelectedObject property unhooks the existing handler. Where the
SelectedObject property is a property of the correct name & type for the type of "domain object" the user control displays. For example if I have a
Person object and a PersonControl that displays a Person object. The
PersonControl would have a SelectedPerson property. Within the
SelectedPerson property I would remove any handlers of the existing Person before assigning the handlers for the new object.

> With regard to reproducing the behaviour, I wonder if the fact that the > controls sink events is significant. If I do the same thing w/o
adding > controls to the form then all is well.
I don't have a good test setup right now to test if having a user

control handle an external object's events is messing up the Closing, I would be surprised if it does.

Did I ask if there are any Exceptions being raised that is causing the
Closing Event to end unexpectedly?

Hope this helps
Jay

"Charles Law" <bl***@nowhere.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
> Hi Jay
>
> m_SelectedControls is an ArrayList, and I am using VS 2003.
>
> I'm removing the controls explicitly because they are user controls that > sink events, and ultimately, I know that as part of this process I must > unhook the handlers from the events. This is part of problem 2 (of 3), that
> if I close a child form that is servicing events, without unhooking the > handlers, then when the event is next raised it still calls the code in the
> old handler, and if the object that was the target of the handler has been
> disposed an exception is thrown to the effect that I cannot access a
control
> that has been disposed.
>
> > Does one of your controls or another handler of the Closing event

cancel
> the
> > Closing event?
>
> None of my controls or handlers attempt to cancel the Closing event.
>
> With regard to reproducing the behaviour, I wonder if the fact that the > controls sink events is significant. If I do the same thing w/o
adding > controls to the form then all is well.
>
> Charles
>
>
> "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in

message
> news:%2****************@TK2MSFTNGP10.phx.gbl...
> > Charles,
> > > This removes the controls prior to the form closing.
> > >
> > > Does any of this make it clearer?
> > What is not clear is why you are removing the controls the explicitly? The
> > Form class will implicitly remove the controls for you.
> >
> > Does one of your controls or another handler of the Closing event

cancel
> the
> > Closing event?
> >
> > Is this VS.NET 2002 or VS.NET 2003?
> >
> > As Ken suggested, I am not able to recreate this behavior, even with > > explicitly removing the controls...
> >
> > What type of collection is m_SelectedControls?
> >
> > Hope this helps
> > Jay
> >
> > "Charles Law" <bl***@nowhere.com> wrote in message
> > news:uj**************@TK2MSFTNGP10.phx.gbl...
> > > Hi Jay
> > >
> > > I see now why it goes to the child forms first. I should have

thought
of
> > > that ;-)
> > >
> > > At the MDI form level I handle the Form.Closed event. At the child > level,
> > I
> > > have overridden the OnClosing method, the first line of which is
> > > MyBase.OnClosing(e). It is in the OnClosing override that I remove all
> the
> > > controls from the form.
> > >
> > > I have simplified the process for making it behave oddly:
> > >
> > > Start MDI form app
> > > Open child form
> > > Close child form
> > > Click X to close app (nothing happens)
> > >
> > > whereas
> > >
> > > Start MDI form app
> > > Open child form
> > > Click X to close app (closes as normal)
> > >
> > > Opening the child form loads some user controls and adds event
handlers
> to
> > > an object on the main form, where methods of the user controls
are
the
> > > target.
> > >
> > > The OnClosing method looks like this
> > >
> > > <code>
> > > Protected Overrides Sub OnClosing(ByVal e As
> > > System.ComponentModel.CancelEventArgs)
> > >
> > > MyBase.OnClosing(e)
> > >
> > > ' When the form closes, remove all controls from the

Controls
> list
> > > and
> > > ' dispose them first
> > > m_SelectedControls.Clear()
> > >
> > > ' First copy the controls to the selected list, to avoid
> > > ' modifying the later loop whilst it is executing
> > > m_SelectedControls.AddRange(Controls)
> > >
> > > For Each ctl As Control In m_SelectedControls
> > > Controls.Remove(ctl)
> > >
> > > ctl.Dispose()
> > > Next ctl
> > >
> > > End Sub
> > > </code>
> > >
> > > This removes the controls prior to the form closing.
> > >
> > > Does any of this make it clearer?
> > >
> > > Charles
> > >
> > >
> > > "Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote

in > message
> > > news:eq**************@TK2MSFTNGP10.phx.gbl...
> > > > Charles,
> > > > > For some reason, when I click the X to close my MDI parent

form, the
> > > > action
> > > > > appears to be re-directed to one of the MDI child forms,
> > > > I would expect when you close the MDI parent that it will be
> re-directed
> > > to
> > > > all of your MDI child forms! As the MDI parent cannot close until all
> > the
> > > > MDI child's are closed.
> > > >
> > > > In other words. MDIParent.Close automatically causes

MDIChild.Close!
> > > >
> > > > > and the parent
> > > > > remains open. I am then unable to close the application.
> > > > Are you canceling the first MDI Child's Form.Closing event?
> > > >
> > > > > What should happen, is that the main MDI form should close,

taking
> the
> > > > child
> > > > > forms with it.
> > > > This is normal .NET behavior, unless you have an event, such as > Closing,
> > > > canceling the operation.
> > > >
> > > > > There is code to loop through the child forms, remove the
> > > > > controls on each of them, and then close the form, but this code > > should
> > > > > execute only when the user clicks a specific menu option.
> > > > The Form.Closing & Form.Closed event occurs for MDI child forms > whether
> > > they
> > > > are closed explicitly via code or implicitly via the MDI parent being
> > > > closed.
> > > >
> > > > > What actually happens is when I click the X to close the main form,
> > the
> > > > > first of the child forms has all its controls removed, and

nothing
> > else
> > > > > happens.
> > > > Which event are you removing all the controls in?
> > > >
> > > >
> > > > Are you handling the Form.Closing & Form.Closed events or did you > > override
> > > > the Form.OnClosing & Form.OnClosed methods. If you overrode
OnClosing,
> > did
> > > > you remember to call the base methods?
> > > >
> > > > Hope this helps
> > > > Jay
> > > >
> > > > "Charles Law" <bl***@nowhere.com> wrote in message
> > > > news:Oh**************@TK2MSFTNGP09.phx.gbl...
> > > > > For some reason, when I click the X to close my MDI parent form, the
> > > > action
> > > > > appears to be re-directed to one of the MDI child forms, and the > > parent
> > > > > remains open. I am then unable to close the application.
> > > > >
> > > > > What should happen, is that the main MDI form should close,

taking
> the
> > > > child
> > > > > forms with it. There is code to loop through the child forms, remove
> > the
> > > > > controls on each of them, and then close the form, but this code > > should
> > > > > execute only when the user clicks a specific menu option.
> > > > >
> > > > > What actually happens is when I click the X to close the main form,
> > the
> > > > > first of the child forms has all its controls removed, and

nothing
> > else
> > > > > happens.
> > > > >
> > > > > I realise that I haven't given much to go on, but I just

wondered
if
> > > > anyone
> > > > > had any thoughts/suggestions of what could cause this.
> > > > >
> > > > > TIA
> > > > >
> > > > > Charles
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>




Nov 20 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.