#614 – Events that Fire When You Switch Between Windows

If your application has multiple windows, the user can switch between the different windows.  The sequence of events when switching from one window (1) to another (2) is as follows:

  • Window.Deactivated  (#1)
  • Window.Activated  (#2)
  • Window.PreviewLostKeyboardFocus  (#1)
  • Window.PreviewGotKeyboardFocus  (#2)
  • Window.IsKeyboardFocusWithinChanged  (#1)
  • Window.IsKeyboardFocusWithinChanged  (#2)
  • Window.IsKeyboardFocusChanged  (#1)
  • Window.IsKeyboardFocusChanged  (#2)
  • Window.LostKeyboardFocus  (#1)
  • Window.GotKeyboardFocus  (#2)
  • Window.Deactivated  (#2)

#613 – Window Event Sequence

The full sequence of events fired for a Window object are as follows.

On application startup, if the Window is the application’s main window.  (Application events are also shown in the correct sequence).

  • Application.Startup
  • Window.Initialized
  • Window.IsVisibleChanged
  • Window.SizeChanged
  • Window.LayoutUpdated
  • Window.SourceInitialized
  • Application.Activated
  • Window.Activated
  • Window.PreviewGotKeyboardFocus
  • Window.IsKeyboardFocusWithinChanged
  • Window.IsKeyboardFocusedChanged
  • Window.GotKeyboardFocus
  • Window.LayoutUpdated
  • Window.Loaded
  • Window.ContentRendered

On normal application shutdown, the event sequence is:

  • Window.Closing
  • Window.IsVisibleChanged
  • Window.Deactivated
  • Application.Deactivated
  • Window.IsKeyboardFocusWithinChanged
  • Window.IsKeyboardFocusedChanged
  • Window.LostKeyboardFocus
  • Window.Closed
  • Application.Exit

When application/window loses focus (user switches to another application):

  • Window.Deactivated
  • Application.Deactivated
  • Window.IsKeyboardFocusWithinChanged
  • Window.IsKeyboardFocusedChanged
  • Window.LostKeyboardFocus

When application/window gains focus (user switches back to application):

  • Application.Activated
  • Window.Activated
  • Window.PreviewGotKeyboardFocus
  • Window.IsKeyboardFocusWithinChanged
  • Window.IsKeyboardFocusChanged
  • Window.GotKeyboardFocus

#612 – Application Event Sequence for Page-Based Applications

When you create a page-based application in WPF, you use a NavigationWindow as the main window, which in turn hosts one or more Page objects.  (If you set the StartupUri property of the Application to point to a Page, a NavigationWindow will be created automatically).

The sequence of Application events that fire for a page-based application are listed below.

When you start the application (assuming that a Page is specified as the StartupUri):

  • Startup
  • Navigating
  • Navigated
  • LoadCompleted
  • Activated

When you shut the application down normally:

  • Deactivated
  • Exit

When you navigate to a new Page:

  • Navigating
  • NavigationProgress  (1 or more times)
  • Navigated
  • LoadCompleted

User is logging out of or shutting down Windows:

  • Deactivated
  • SessionEnding

Application gains focus:

  • Activated

Application loses focus:

  • Deactivated

#611 – Set Application Exit Code in Exit Event Handler

If you’re running applications from the command line in Windows, you can return an exit code from the application and use it to indicate whether the application was successful at doing whatever it was supposed to do.  Traditionally, an exit code of 0 indicates that the application completed successfully and positive values indicate errors.

To set a WPF application’s exit code, set the ApplicationExitCode property of the ExitEventArgs object in the application’s Exit event.

        private void Application_Exit(object sender, ExitEventArgs e)
        {
            // Assume we have a boolean variable indicating whether the
            //   application did its work successfully

            // Use 0 to indicate success, 1 to indicate that something went wrong
            e.ApplicationExitCode = (everythingWorkedOk) ? 0 : 1;
        }

You could then check this code in a .bat file:

WpfApplication11.exe

REM This evaluates to true if exit code was >= 1
if errorlevel 1 (
    echo Failure
) else (
    echo Success !
)

echo Actual exit code was %errorlevel%

#610 – Application Event Sequence

The sequence of events for an application’s main Application object that are fired are as follows (all events listed in the order that they fire):

When you start the application:

  • Startup
  • Activated

When you shut the application down normally (i.e. close main window):

  • Deactivated
  • Exit

If the application experiences an unhandled exception:

  • DispatcherUnhandledException

If user is logging out of or shutting down Windows:

  • Deactivated
  • SessionEnding

Application gets focus:

  • Activated

Application loses focus:

  • Deactivated

#609 – Perform Initialization in Window.Loaded Handler

Quite often you will want to perform some sort of initialization when your application first starts up.  You could add code to do this in the constructor for your main Window object.  For example:

<StackPanel>
    <Label Name="lblToday" Content="Today is XXX"/>
</StackPanel>

 

        public MainWindow()
        {
            this.InitializeComponent();

            lblToday.Content = string.Format("Today is {0}", DateTime.Now.ToShortDateString());
        }

A better method, however, is to do this initialization in a handler for the Window.Loaded event.

        public MainWindow()
        {
            this.InitializeComponent();

            this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            lblToday.Content = string.Format("Today is {0}", DateTime.Now.ToShortDateString());
        }

An exception that originates from the window’s constructor will be thrown as a XamlParseException (with the original exception in the InnerException). If, however, the exception originates from an event handler, it will not be wrapped in another exception.

#608 – Class Handlers Are Invoked Before Instance Handlers

If you have a class handler defined for a particular routed event, as well as one or more instance handlers on different elements, when the event fires, the class handler will be invoked before any instance handlers.

        public MainWindow()
        {
            this.InitializeComponent();

            // Class handler--called when user clicks on ANY Button
            EventManager.RegisterClassHandler(
                typeof(Button),
                ButtonBase.ClickEvent,
                new RoutedEventHandler(HandleAllButtons));
        }

        private void HandleAllButtons(object sender, RoutedEventArgs e)
        {
            Button b = (Button)e.Source;
            Trace.WriteLine(string.Format("* (CLASS handler) You clicked on [{0}] button", b.Content));
        }

        // Click handler for Eliot button
        private void btnEliot_Click(object sender, RoutedEventArgs e)
        {
            Trace.WriteLine("* (INSTANCE handler) You clicked on Eliot button");
        }