#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

#206 – WPF Applications Use an Event-Driven Paradigm

WPF uses an event-driven programming model.  In event-driven programs, the user interface elements are first rendered and then the application waits for one or more events to occur.  Events typically originate from the user and normally represent the user interacting with the application through some input device.  For example, a user clicks on a button by clicking with the left mouse button.

When an event occurs, some code in the application executes, in a method known as an event handler.  The application will then typically perform some action in response to the event.  (E.g. open a new window, based on a button being clicked).

Events can also originate from a source other than the user.  For example, an internal software timer might Tick every 100 ms, generating an event for each tick.

#205 – The WPF GUI Pipeline

In WPF, there are a number of different actors or elements that impact how data (or content) will be presented to the user.  The various elements can be thought of a “pipeline”, with data flowing in at one end and final GUI elements coming out of the other end.

The different elements in the GUI pipeline are:

  • Data binding – Data from some object is bound to one or more controls
  • Value Converters – Bound data may be converted to another format
  • Templates – Control and data templates specify constituent elements for a control
  • Presenters – ContentPresenter and ItemsPresenter act as placeholders within a template, indicating where the content goes
  • Layout – Determine position and size of all elements
  • Style – Apply a predefined style, which specifies one or more property values

#204 – Detecting Key Presses in a WPF Window

You can detect key presses in a class that derives from Window by overriding the OnKeyDown and OnKeyUp methods (which in turn fire the KeyDown and KeyUp events).  

These key down/up methods are invoked in addition to any control that has focus and might also provide key down/up methods.

For example, a TextBox also has KeyDown and KeyUp events that are fired.  If a user presses a key while a TextBox has focus, the sequence of events is:

  • KeyDown in TextBox
  • KeyDown in Window
  • KeyUp in TextBox
  • KeyUp in Window

Here’s an example:

    public partial class MainWindow : Window
    {
        private static Key[] vowels = { Key.A, Key.E, Key.I, Key.O, Key.U };

        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);

            if ((vowels.Contains(e.Key)) && (!e.IsRepeat))
                lblVowels.Content = lblVowels.Content + e.Key.ToString();
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            base.OnKeyUp(e);

            if (vowels.Contains(e.Key))
                lblVowels.Content = lblVowels.Content + ",";
        }

#203 – Window Size and Location Are Specified in Device Independent Units

The Window class has Left and Top properties that specify the location on the screen of the left and top sides of the window.  It also has Width and Height properties that specify the window’s size.  All of these are expressing in device independent units.

If the current DPI setting is 96 dpi (dots per inch), the WPF units are equivalent to pixels.  I.e. A window specified as 96 units high would appear as 1 inch high.  If the DPI setting is different, the specified WPF units are scaled by dpi/96 to get the resulting pixel value.

In other words:    # pixels = (# WPF Units) * (DPI / 96)

The reason for this is so that WPF applications will appear at roughly the same dimensions on various monitors, regardless of the pixel density.