An application that uses WPF typically consists of a collection of XAML pages and their supporting code-behind files. In addition to page-level processing, WPF applications need to perform inter-page tasks such as storing page state when the user goes to a different page, passing data between pages, detecting when a new page loads, and so on.
A WPF application can either be hosted inside a Web Browser or it can be stand-alone Windows application:
· XAML Broswer applications: These are hosted in a web browser, are not installed on the user's machine, and cannot run offline. They run in the Internet zone which limits their access to potentially unsafe system resources. These applications therefore do not require user permissions to run.
· XAML Windows Applications: These applications are hosted in a Window or NavigationWindow class, are installed on the user's machine and can run offline and online. They have full access to system resources and require user permission to be installed and run.
The application model is at the core of WPF development. The following presents an overview of the WPF application model which consists of the Application Management, Windows, Navigation, and Hosting. These are briefly discussed below:
All applications that use Windows Presentation Foundation (WPF) are associated with an Application object. This object represents the application to the operating system and enables the system to communicate with the application. The Application object supports properties, methods, and events that enable you to make a collection of XAML pages into a coherent application. The Application object does the following:
1. Handles message dispatching, i.e., you do not need to implement a message loop.
2. Supports navigation between pages.
3. Provides a way to share data across pages.
4. Supports a variety of of navigation and application-level events.
The fundamental purpose of a window is to host and display content. The type of content that a window hosts depends on the type of data that an application operates over, which can include media, Extensible Application Markup Language (XAML) pages, Web pages, documents, database tables and records, and system information. Pages are displayed in windows and navigation to a different page takes place either in a window, or from one window to another. The two main window objects are Window and NavigationWindow. These two objects support:
1. Window properties: size, position, etc.
2. Window activato: creating and closing.
3. Window events: mouse moves, size changes, etc.
4. Modal dialog boxes.
5. Navigation-related features.
WPF applications are similar to Web applications. Typically, a user interact with a page and then clicks a link to navigate to another page. WPF supports flexible navigation, including:
1. Navigation events which notify users when navigation starts and when a page loads.
2. Navigation methods to navigate to a selected page.
3. Structured navigation, which provides a powerful approach to navigation.
4. And many other navigation features.
A Windows-based application consists of some standard plumbing, including both an entry point and a message loop, and possibly may also require one or more of the following common application services: Processing command-line parameters, returning an exit code, application-scope state, detecting and responding to unhandled exceptions, and managing application lifetime. WPF centralizes both plumbing and services within a single type, System.Windows.Application, which you can use from markup and/or code.
The core object of a WPF application is therefore, the Application object. It has the following programming-characteristics:
· It is global to the application. Every page has access to the Application object.
· It is created at startup and is available for the duration of the applications.
· It is local to the user's system.
The following subsections show how to use the Application object
A WPF application is defined using both XAML and code-behind files. XAML files allow you to declaratively set application properties, resources, and register events. Code-behind files allow you to handle the events and implement application-specific behavior. A skeletal WPF application looks like this:
<!-- App.xaml -->
<Application x:Class="WPFApplication.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
</Application.Resources>
</Application>
// App.xaml.cs
namespace WPFApplication
{
public partial class App
: System.Windows.Application
{
}
}
An XAML Markup file and its associated code-behind file work together as follows:
1. In XAML, the <Application> element includes the x:Class attribute which instructs the .NET Builder (MSBuild) to create a partial class for the XAML file. This requires the addition of an XAML namespace declaration http://schemas.microsoft.com/winfx/2006/xaml. This partial and auto-generated class implements InitializeComponent which is called to register events and set properties that are implemented in the markup. For the example above, this partial class is called App.g.cs.
2. In the code-behind file, the class must be partial and with the same name specified in the x:Class attribute. This partial class must also derive from System.Windows.Application (as shown in the skeletal code.)
Finally, note that VS.NET configures the build action for the application markup file as ApplicationDefinition:

Note that for any WPF application, the Properties window for file App.xaml indicate that Build Action is set to ApplicationDefinition. The effect of the combination of application definition and MSBuild configuration causes MSBuild to generate code like the following:
public class App : Application
{
public App() { }
[STAThread]
public static void
{
App app =
new App();
app.InitializeComponent();
app.Run();
}
public void InitializeComponent()
{
//
Register XAML-declared events
...
// Set
XAML-declared properties
}
}
In other words, the one and only entry point is auto-generated by MSBuild.
After calling app.Run (see Main method above), the Application object establishes required infrastructure and then fires the Startup event to signify that an application has started:
<Application Startup="App_StartupHandler" ... />
public partial class App :
Application
{
void App_StartupHandler(object
sender, StartupEventArgs e)
{
//
Application is running
}
}
Note that the Windows and MainWindow properties of the Application object allow you to manage the application windows. Windows property is a reference to a collection that contains all open windows in the application, while the MainWindow property is a reference to main window of the application.
Because most Windows applications display a UI when they begin running, the Startup event handler is an ideal location to do so. For standalone applications, this involves showing the main window:
public partial class App :
Application
{
void App_Startup(object sender, StartupEventArgs e)
{
// If you implemeneted your own main window:
MyMainWindow
window = new MyMainWindow();
window.Show();
// Or, if you would like to use one of the built-in windows
// to act as the main window
NavigationWindow mywindow = new NavigationWindow();
mywindow.Navigate( new Uri("StartupPage.xaml",
UriKind.RelativeOrAbsolute));
mywindow.Show();
}
}
If the only reason you handle Startup is to show a window, you can set the StartupUri attribute in markup instead. The code then looks like this:
<!-- App.xaml -->
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="App"
StartupUri="MyMainWindow.xaml"
/>
<Application.Resources>
</Application.Resources>
</Application>
// App.xaml.cs
public partial class App : System.Windows.Application
{
// Empty implementation
}
<!-- MyMainWindow.xaml -->
<Window x:Class="WPFApplication.MyMainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPFApplication"
Height="300" Width="300">
<Grid>
<!--
GUI elements come here -->
</Grid>
</Window>
// MyMainWindow.xaml.cs
public partial class MyMainWindow : System.Windows.Window
{
public MyMainWindow()
{
InitializeComponent();
}
}
Note 1: Sometimes, the UI may be composed entirely of pages (instances of Page) instead of windows (instances of Window). In this case, you can still use StartupUri to specify the start up page. So what happens when you launch the application? WPF run time will automatically create a window frame (derives from NavigationWindow) for you and place the page in that window.
Note 2: With respect to showing a UI, the main reason to use a handler for Startup event instead of setting StartupUri, is to:
· Instantiate the class that implements the UI by using a non-default constructor, or
· Set properties on it before showing it, or
· Retrieve and process the command-line arguments for your application.
Getting the
Application Object
The Application object is created automatically on start-up. A reference to the
Applicaton
object can obtained as follows:
Application app = System.Windows.Application.Current;
// Get Application object
ap.Current.Shutdown(); // Shows how to use the
Application object
During application initialization, WPF retrieves the command-line arguments from the operating system and passes them to the Startup event handler via the Args property of the StartupEventArgs parameter. You can retrieve and store the command-line arguments as follows:
void App_Startup(object
sender, StartupEventArgs e)
{
// Don't bother if no command line
args were passed.
// NOTE: e.Args is never null - if
no command line args were passed, e.Args.Length
is 0.
if (e.Args.Length == 0)
return;
// Parse command line args for args in the following
format:
// /argname:argvalue
/argname:argvalue /argname:argvalue
...
string pattern = @"(?<argname>/\w+):(?<argvalue>\w+)";
foreach (string arg in e.Args)
{
Match match
= Regex.Match(arg,
pattern);
// If
match not found, command line args are improperly
formed.
if
(!match.Success)
throw new ArgumentException("Incorrect cmd
line args. Use /argname:argvalue.");
// Store
command line arg and value
CommandLineArgs[match.Groups["argname"].Value]
= match.Groups["argvalue"].Value;
}
}
Unhandled exceptions can be trapped by providing a handler for the Application.DispatcherUnhandledException event which occurs when an exception is raised by the application but not handled:
<Application DispatcherUnhandledException="App_DispatcherUnhandledException" ... />
public partial class App :
Application
{
void App_DispatcherUnhandledException(object
sender, DispatcherUnhandledExceptionEventArgs e)
{
// Process
unhandled exception. Th exception itself can be retreives using
// e.Exception.
It may be a non-recoverable exception such as StackOverflowException,
// or it may be a recoverable
exception such as FileNotFoundException.
...
// Prevent default unhandled exception processing which shuts
the application down
e.Handled
= true;
}
}
Note: If an unhandled exception is raised and the DispatcherUnhandledException event is not handled, or the event is handled and Handled is set to false, the application will shut down straight away. Furthermore, no other events that are implemented by Application are raised. Consequently, you will need to handle DispatcherUnhandledException if your application has code that is required to run prior to the application shutting down.
Handling
Application-related events
An application object can handle events in two ways:
1. Attach an event handler. This was demonstrated earlier
2. Override the corresponding OnX method. This approach follows the .NET event model guideline The override of the protected virtual method can raise the event, suppress it, or forwared it to a different event. With this approach, the override is invoked when the specific event fires, but the override needs to call the base method to actually raise the event so that other listeners can get the event. If the override does not call the base method then other listeners will not get to handle the event
Depending on the type of application, an application shuts down when either all its windows are closed, or when its main window is closed. Because these two scenarios are fairly common, you can configure the application to automatically shut down when they happen by setting ShutdownMode to one of the following ShutdownMode enumeration values:
· OnLastWindowClose (default)
· OnMainWindowClose
· OnExplicitShutdown
For example:
<Application ShutdownMode="OnMainWindowClose" ... />
Note 1: The main window is the window that is referenced by the System.Windows.Application.MainWindow
property. By default, the value of this property is a reference to the first
window that is instantiated within an application, although the value can be
changed programmatically afterwards.
Note 2: When a user ends their session (i.e., log off), Windows notifies
each currently running application that the user is logging off. Applications
that allow users to edit data (i.e., word processors and spread sheets, for
example) are most likely to take advantage of this capability. Consequently,
applications can use this opportunity to check that their application data is
saved and, if not, give the user the opportunity to prevent Windows from
shutting down.
The Application object detects when Windows raises the session ending notification and raises the SessionEnding event when it happens. You can handle SessionEnding event to detect, respond to, and cancel session ending:
<Application SessionEnding="App_SessionEnding" ... />
public partial class App :
Application
{
void App_SessionEnding(object
sender, SessionEndingCancelEventArgs e)
{
//
Application-specific logic ...
}
}
Note 3: If shutdown is explicitly initiated by an application, the lifetime of an application will end. Before ending, applications may need to perform final processing such as persisting application state. For these situations, you can handle the Exit event.
<Application Exit="App_Exit" ... />
public partial class App :
Application
{
void App_Exit(object
sender, ExitEventArgs e)
{
//
Application-specific logic to do any required clean up
}
}
The following figure illustrates the key events in the lifetime of an application, and the sequence in which they are raised:

The Application object implements the Properties property to expose state that can be shared across the entire application. The following provides an example of using Property:
// Set an
application-scope property with a custom type
CustomType customType = new
CustomType();
Application.Current.Properties["CustomType"] = customType;
// Get an
application-scope property
// NOTE: Need to convert since Application.Properties
is a dictionary of System.Object
CustomType customType = (CustomType)Application.Current.Properties["CustomType"];
The Application object also implements the Resources property to allow developers to share user interface (UI) resources across an application. The following provides an example of using Resources:
// Set an
application-scope resource
Application.Current.Resources["ApplicationScopeResource"]
= Brushes.White;
// Get an
application-scope resource
Brush whiteBrush = (Brush)Application.Current.Resources["ApplicationScopeResource"];
(WPF) offers special support for configuring, identifying, and using data files which include images, video, audio, and XAML files. This support rsolves around a specific set of application data file types, including:
The following sections discuss how to configure and use these application data files.
If an application data file must always be available to an application, compile it into an application's main executable assembly or one of its referenced assemblies. In Microsoft Visual Studio 2005, you create a resource file by adding a file to a project and setting its Build Action to Resource. When the project is built, MSBuild compiles the resource into the assembly.
The following example shows how to load a Page resource file and set it as the content of a Frame:
Uri uri = new Uri("/PageResFile.xaml", UriKind.Relative);
StreamResourceInfo info = Application.GetResourceStream(
uri );
XamlReader reader =new XamlReader();
Page page = (Page)reader.LoadAsync(info.Stream);
this.pageFrame.Content = page;
// Display page in the frame
A short cut version of the above code can be done in both C# and XAML:
Uri uri = new Uri("/PageResFile.xaml", UriKind.Relative);
this.pageFrame.Source = uri;
<Frame Name="pageFrame" Source="PageResFile.xaml" />
Note: In Microsoft Visual Studio 2005, if you add a new Window, NavigationWindow, Page, FlowDocument, or ResourceDictionary to a project, the Build Action for the markup file will default to Page. When a project with Page items is compiled, the XAML items are converted to binary format and compiled into the associated assembly. Consequently, these files can be used in the same way as typical resource files.
Use content files when your application requires some data files that you want to be able to modify without recompiling the assembly that consumes them. Although content files are not compiled into an assembly, assemblies are compiled with metadata that establishes an association with each content file.
To add a content file to a project, modify its properties as follows:

The following example shows how to load a content file:
Uri uri = new
Uri("/ReadMe.txt", UriKind.Relative);
StreamResourceInfo info = Application.GetContentStream(
uri );
XamlReader reader =new XamlReader();
Page page = (Page)reader.LoadAsync(info.Stream);
this.pageFrame.Content = page;
A short cut version of the above code can be done in both C# and XAML:
Uri uri = new Uri("/ReadMe.txt", UriKind.Relative);
this.pageFrame.Source = uri;
<Frame Name="pageFrame" Source="ReadMe.txt" />