Translate

Saturday, 31 August 2013

WPF Application Events

WPF Application Events

You can best see the life cycle of a standard application in the set of events that it
exposes:*
• Startup
• Activated
• Deactivated
• DispatcherUnhandledException
• SessionEnding
• Exit

Startup event

The Application object’s Startup event is fired when the application’s Run method is
called, and it is a useful place to do application-wide initialization, including the
handling of command-line arguments, which are passed in the StartupEventArgs:
void App_Startup(object sender, StartupEventArgs e) {
for (int i = 0; i != e.Args.Length; ++i) {
// do something useful with each e.Args[i]
...
}
}

Activated and Deactivated events

The Activated event is called when one of the application’s top-level windows is activated
(e.g., via a mouse click or Alt-Tab). Deactivated is called when your application is
active and another application’s top-level window is activated. These events are handy
when you want to stop or start some interactive part of your application:
void App_Activated(object sender, EventArgs e) {
ResumeGame( );
}
void App_Deactivated(object sender, EventArgs e) {
PauseGame( );
}

DispatcherUnhandledException event

The application’s dispatcher is an object that routes events to the correct place, including
unhandled exceptions. In the event that you’d like to handle an exception otherwise
unhandled in your application—maybe to give the user a chance to save his current
document and exit—you can handle the DispatcherUnhandledException event:
Application Lifetime | 45
void App_DispatcherUnhandledException(
object sender, DispatcherUnhandledExceptionEventArgs e) {
string err = "Oops: " + e.Exception.Message);
MessageBox.Show(err, "Exception", MessageBoxButton.OK);
// Only useful if you've got some way of guaranteeing that
// your app can continue reliably in the face of an exception
// without leaving this AppDomain in an unreliable state...
//e.Handled = true; // stop exception from bringing down the app
}
The Exception property of the DispatcherUnhandledExceptionEventArgs event argument
is useful to communicate to your users what happened, whereas the Handled
property is useful to stop the exception from actually bringing down the application
(although this is a dangerous thing to do and can easily result in data loss).

SessionEnding event

The SessionEnding event is called when the Windows session itself is ending (e.g., in
the event of a shutdown, logoff, or restart):
void App_SessionEnding(object sender, SessionEndingCancelEventArgs e) {
if (MessageBox.Show(
e.ReasonSessionEnding.ToString( ),
"Session Ending",
MessageBoxButton.OKCancel) == MessageBoxResult.Cancel) {
e.Cancel = true; // stop the session from ending
}
}
The ReasonSessionEnding property of the SessionEndingCancelEventArgs event argument
is one value in the ReasonSessionEnding enumeration:
namespace System.Windows {
public enum ReasonSessionEnding {
Logoff = 0,
Shutdown = 1,
}
}
The Cancel property is useful if you’d like to stop the session from ending, although
this is considered rude, and more progressive versions of Windows (like Vista) may
not let you change its decision to end a session at all.

Exit event

The Exit event is called when the application is actually exiting, whether the last
window has gone away, the Application.Shutdown method is called, or the session is
ending. One of the overloads of the Shutdown method allows the programmer to pass
an integer exit code, which is ultimately exposed by the process for use by your favorite Win32 process examination APIs. By default, this value is zero, but you can
observe or override it in the handlers for this event:
void App_Exit(object sender, ExitEventArgs e) {
e.ApplicationExitCode = 452; // keep 'em guessing...
}



Saturday, 17 August 2013

WPF Top-Level Windows

WPF Top-Level Windows

A top-level window is a window that is not contained within or owned by another
window (window ownership is discussed in more detail later). A WPF application’s
main window is the top-level window that is set in the MainWindow property of the
Application object. This property is set by default when the first instance of the
Window class is created and the Application.Current property is set. In other words,
by default, the main window is the top-level window that’s created first after the
application itself has been created. If you like, you can override this default by setting
the MainWindow property manually.
In addition to the main window, the Application class provides a list of top-level
windows from the Windows property. This is useful if you’d like to implement a Window
menu.

To implement the Window menu, we first start with a MenuItem element:
<!-- Window1.xaml -->
<Window ...>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Menu>
<MenuItem Header="Window" x:Name="windowMenu">
<MenuItem Header="dummy item" />
</MenuItem>
</Menu>
</Grid>
</Window>
MenuItem is a HeaderedItemControl (as described in Chapter 5), which means that it
has header content that we’ll use to hold the name of the menu item (“Window”),
and subcontent that we’ll use to hold the menu items for each top-level window.
Notice the use of a dummy subitem to start with. Without this dummy item, you
won’t be able to get notification that the user has asked to show the menu items
(whether via mouse or via keyboard).
To populate the Window menu, we’ll handle the menu item’s SubmenuOpened event:
public partial class Window1 : Window {
...
public Window1( ) {
InitializeComponent( );
windowMenu.SubmenuOpened += windowMenu_SubmenuOpened;
}
void windowMenu_SubmenuOpened(object sender, RoutedEventArgs e) {
windowMenu.Items.Clear( );
foreach (Window window in Application.Current.Windows) {
MenuItem item = new MenuItem( );
item.Header = window.Title;
item.Click += windowMenuItem_Click;
item.Tag= window;
item.IsChecked = window.IsActive;
windowMenu.Items.Add(item);
}
}
void windowMenuItem_Click(object sender, RoutedEventArgs e) {
Window window = (Window)((MenuItem)sender).Tag;
window.Activate( );
}
}
When the SubmenuOpened event is triggered, we use the Application object’s Windows
property to get a list of each top-level Window, creating a corresponding MenuItem for
each Window.


Application Shutdown Modes

Some applications work naturally with the idea of a single main window. For example,
many applications (drawing programs, IDEs, Notepad, etc.) have a single top-level window
that controls the lifetime of the application itself (i.e., when the main window goes
away, the application shuts down). On the other hand, some applications have multiple
top-level windows or some other kind of lifetime control that’s independent of a single
main window.* You can specify when your application shuts down by setting the application’s
ShutdownMode property to one of the values of the ShutdownMode enumeration:
namespace System.Windows {
public enum ShutdownMode {
OnLastWindowClose = 0, // default
OnMainWindowClose = 1,
OnExplicitShutdown = 2,
}
}
The OnMainWindowClose value is useful when you’ve got a single top-level window,
and the OnLastWindowClose value is useful for multiple top-level windows (and is the
default). In either of these cases, in addition to the automatic application shutdown
the ShutdownMode policy describes, an application can also be shut down manually by
calling the Application object’s Shutdown method. However, in the case of
OnExplicitShutdown, the only way to stop a WPF application is by calling Shutdown:
public partial class Window1 : System.Windows.Window {
...
void shutdownButton_Click(object sender, RoutedEventArgs e) {
Application.Current.Shutdown();
}
}
You can change the shutdown mode in code whenever you like, or you can set it in
the application definition XAML:
<Application
x:Class="AppWindowsSample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml"
ShutdownMode="OnExplicitShutdown" />

Saturday, 3 August 2013

WPF Applications and Settings

WPF Application Lifetime


In the Windows sense, an “application” is an address space and at least one thread of
execution (a.k.a. a “process”). In the WPF sense, an application is a singleton object
that provides services for UI components and UI programmers in the creation and
execution of a WPF program. More specifically, in WPF, an application is an
instance of the Application class from the System.Windows namespace.

WPF Explicit Application Creation

Example . Creating an application explicitly
using System;
using System.Windows; // the home of the Application class
class Program {
[STAThread]
static void Main( ) {
Application app = new System.Windows.Application();
Window1 window = new Window1( );
window.Show( );
app.Run();
}
}

Here, we’re creating an application inside an STA thread,* creating a window and
showing it, and then running the application. While the application is running, WPF
processes Windows messages and routes events to WPF UI objects as necessary.
When the Run method returns, messages have stopped being routed and generally
don’t start again (unless you show a modal window after the Run method returns, but
that’s not something you’ll usually do). During its lifetime, the application provides
various services.

WPF Application Access

One of the services the Application class provides is access to the current instance.
Once an instance of the Application class is created,† it’s available via the Current
staticproperty of the Application class. For example, the code in Example 2-1 is
equivalent to the code in Example 
Here, in the process’s entry point, we’re creating an application, creating and showing
the main window, and then running the application. Creation of the Application
object fills the static Application.Current property. Access to the current application
is very handy in other parts of your program where you don’t create the application
or when you let WPF create the application for you itself.
* The “Single Threaded Apartment” (STA) was invented as part of the native Component Object Model
(COM) to govern the serialization of incoming COM calls. All Microsoft presentation frameworks, native or
managed, require that they be run on a thread initialized as an STA thread so that they can integrate with
one another and with COM services (e.g., drag-and-drop).
† WPF makes sure that, at most, one Application object is created per application domain. For a discussion
of .NET application domains, I recommend Essential .NET, by Don Box with Chris Sells (Addison-Wesley
Professional)

Example . Implicitly filling in the Application.Current property
using System;
using System.Windows;
class Program {
[STAThread]
static void Main( ) {
// Fills in Application.Current
Application app = new System.Windows.Application();
Window1 window = new Window1( );
window.Show( );
Application.Current.Run(); // same as app.Run( )
}
}


Implicit Application Creation

Because a Main method that creates and runs an application is pretty darn common,
WPF can provide the process’s entry point for you. WPF projects generally designate
one XAML file that defines the application. For example, if we had defined our
application in a XAML file with code behind, it would look like Example 2-3.
Notice that Example 2-3 is defining a custom application class in this code
(ImplicitAppSample.App) that derives from the Application class. In the OnStartup
override, we’re only creating a window and showing it, assuming WPF is going to
create the Main for us that creates the instance of the App class and calls the Run
method (which calls the OnStartup method). The way that WPF knows which XAML
file contains the definition of the Application class is that the Build Action is set to
ApplicationDefinition.

The ApplicationDefinition Build Action lets WPF know which class is our application
and hooks it up appropriately in a Main method it generates for us, which saves
us from writing several lines of boilerplate code.
Example  Declaring an application in XAML
<!-- App.xaml -->
<Application
x:Class="ImplicitAppSample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />
// App.xaml.cs
using System;
using System.Windows;
namespace ImplicitAppSample {
public partial class App : System.Windows.Application {
protected override void OnStartup(StartupEventArgs e) {
// let the base class have a crack
base.OnStartup(e);
// WPF itself is providing the Main that creates an
// Application and calls the Run method; all we have
// to do is create a window and show it
Window1 window = new Window1( );
window.Show( );
}
}
}

Thursday, 1 August 2013

Where WPF applications Works

WPF Where and we 


WPF applications have a great deal of power, at which this chapter can only hint.
The base services of the application aren’t too surprising, but the support for pagebased
navigation and browser hosting certainly adds a new capability for Windows
applications, further enhanced with .NET 2.0 ClickOnce support.
Building your application is a matter of grouping controls in containers—either single
content containers, like windows or buttons, or multiple content containers that
provide layout capabilities, like the canvas and the grid.
When bringing your controls together, you’ll want to populate them with data that’s
synchronized with the in-memory home of the data, which is what data binding is
for, and keep them pretty, which is what styles are for. If you want to declare data or
styles in your XAML, you can do so using resources, which are just arbitrarily named
objects that aren’t used to render the WPF UI directly.
If no amount of data or style property settings makes you satisfied with the look of
your control, you can replace it completely with control templates, which can comprise
other controls or graphics primitives. In addition, you can apply graphics
operations, like rotating, scaling, or animation, to 2D or 3D graphics primitives or
controls in WPF’s integrated way. These elements can further be gathered into documents
for viewing or printing.

More recently, the Windows Presentation Foundation (WPF) happened. Initially it
felt like another way to create my windows, menus, dialogs, and child controls.
However, WPF shares a much deeper love for content than has yet been provided by
any other Windows programming framework.
To support content at the lowest levels, WPF merges controls, text, and graphics
into one programming model; all three are placed into the same element tree in the
same way. And although these primitives are built on top of DirectX to leverage the
3D hardware acceleration that is dormant when you’re not running the latest twitch
game, they’re also built into .NET, providing the same productivity boost to WPF
programmers that Windows Forms programmers enjoy.
To help you arrange the content, whether in fixed or flow layout, WPF provides container
elements that implement various layout algorithms in a way that is completely
independent of the content they’re holding.
To help you visualize the content, WPF provides data binding, control templates,
and animation. Data binding produces and synchronizes visual elements on the fly
based on your content. Control templates allow you to replace the complete look of
a control while maintaining its behavior. Animation brings your user interface control
to life, giving your users immediate feedback as they interact with it. These features
give you the power to produce data visualizations so far beyond the capabilities
of the data grid, the pinnacle most applications aspire to, that even Edward Tufte
would be proud.
Combine these features with ClickOnce for the deployment and update of your
WPF applications, both as standalone clients and as blended with your web site
inside the browser, and you’ve got the foundation of the next generation of Windows

applications.