none
Why doesn't the Unloaded event get called on my Window?

    Question

  • I've added an event handler for the Unloaded event to a my Application Window, but it doesn't get called at application shutdown. Why not?

    Thanks,
    --Jeremy

    Thursday, December 20, 2007 12:18 AM

Answers

  • Jeremy Chaney wrote:

    Is there any WPF way of knowing when a control gets destroyed?

     

    Not really.  At this point, we are just talking about CLR objects, so WPF doesn't come into play.  You could implement a destructor, but that's not generally a good solution, since it pushes your object into a higher generation for garbage collection (which can have pretty negative perf implications).

     

    You could also implement IDisposable, but then you are placing a burden on your users to actually dispose your user control.  That's not really WPF friendly.

     

    It's fine to use Unloaded to know when your user control is removed from the tree.  Just realize that unloaded may fire if the user dynamically changes the OS theme (because the tree is being rebuilt for the new theme).  The only time it won't fire is when the application has entered its "shutting down" state.  Usually this isn't a problem because the app is about to go away anyway.  But if you truly have critical data that must be saved even when the app is shutting down, using the Exit event as a failsafe seems appropriate.

    Thursday, December 20, 2007 8:31 PM

All replies

  • Are you sure you want the Unloaded event?  This is a FrameworkElement event that fires when the element is removed from its visual tree.  This could happen for many reasons... not just when a window is closing.  You might be better off with the Window's Closed event (or the Closing event).

     

    To answer your specific question, the Unloaded event no longer fires for elements once an application begins to shut down.  When this occurs depends on the ShutdownMode property of the Application.  The default ShutdownMode is OnLastWindowClosed.  So as soon as you close the last window, the framework essentially calls Application.Current.Shutdown().  From that point on, you will not receive the Unloaded event.

     

    To verify that this is happening in your case, simply change the ShutdownMode property in App.xaml, as follows:

     

    Code Block

     

    <Application

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        StartupUri="Window1.xaml" ShutdownMode="OnExplicitShutdown">

      <Application.Resources>

      </Application.Resources>

    </Application>

     

     

    You will then see that your Unloaded event fires when the window is closed.  Of course, the application will continue to run indefinitely unless you explicitly call Application.Current.Shutdown() in your unloaded event (or some such place).

    Thursday, December 20, 2007 6:23 AM
  • OK, that makes more sense now- too bad the MS documentation doesn't explain any of that...

    In my initial post I referenced my app window just because it was easier to explain. What I really need, though is to do some clean up in a UserControl when it gets closed. If I use the Unloaded event then it gets called when the Window hosting the control is closed- unless it is being closed because the App is exiting. In my app Window I can override OnClosing, but I obviously can't in my UserControl.
    Thursday, December 20, 2007 4:44 PM
  • If you have some cleanup code that needs to run prior to the application exiting, your user control can attach an Exit handler for the Application.Current.Exit event.  If you have both an Unloaded and an Exit handler, you will want to have a flag to ensure that your cleanup routine only executes once because you might receive both events depending on the application in which you are hosted.

    Thursday, December 20, 2007 7:09 PM
  • Based on your previous statements about Unload firing for a variety of reasons, not just shutdown, I'd like to avoid using it. Also, my cleanup code needs to run when the popup window is closed- which might happen because the user closed it, or it might happen because the app is exiting. Is there any WPF way of knowing when a control gets destroyed?

    Thursday, December 20, 2007 7:14 PM
  • Jeremy Chaney wrote:

    Is there any WPF way of knowing when a control gets destroyed?

     

    Not really.  At this point, we are just talking about CLR objects, so WPF doesn't come into play.  You could implement a destructor, but that's not generally a good solution, since it pushes your object into a higher generation for garbage collection (which can have pretty negative perf implications).

     

    You could also implement IDisposable, but then you are placing a burden on your users to actually dispose your user control.  That's not really WPF friendly.

     

    It's fine to use Unloaded to know when your user control is removed from the tree.  Just realize that unloaded may fire if the user dynamically changes the OS theme (because the tree is being rebuilt for the new theme).  The only time it won't fire is when the application has entered its "shutting down" state.  Usually this isn't a problem because the app is about to go away anyway.  But if you truly have critical data that must be saved even when the app is shutting down, using the Exit event as a failsafe seems appropriate.

    Thursday, December 20, 2007 8:31 PM