Translate

Wednesday, 30 October 2013

WPF Routed Events

WPF Routed Events


The .NET Framework defines a standard mechanism for managing events. A class
may expose several events, and each event may have any number of subscribers.
WPF augments this standard mechanism to overcome a limitation: if a normal .NET
event has no registered handlers, it is effectively ignored.
Consider what this would mean for a typical WPF control. Most controls are made
up of multiple visual components. For example, suppose you give a button a very
plain appearance consisting of a single Rectangle, and provide a simple piece of text
as the content. (Chapter 9 describes how to customize a control’s appearance.) Even
with such basic visuals, there are still two elements present: the text and the rectangle.
The button should respond to a mouse click whether the mouse is over the text
or the rectangle. In the standard .NET event handling model, this would mean registering
a MouseLeftButtonUp event handler for both elements.
This problem would get much worse when taking advantage of WPF’s content
model. A Button is not restricted to having plain text as a caption—it can contain any
object as content. The example is not especially ambitious, but even
this has six visible elements: the yellow outlined circle, the two dots for the eyes, the
curve for the mouth, the text, and the button background itself. Attaching event
handlers for every single element would be tedious and inefficient. Fortunately, it’s
not necessary.
WPF uses routedevents , which are rather more thorough than normal events. Instead
of just calling handlers attached to the element that raised the event, WPF walks the
tree of user interface elements, calling all handlers for the routed event attached to
any node from the originating element right up to the root of the user interface tree.
This behavior is the defining feature of routed events, and is at the heart of event
handling in WPF.
Example 4-1 shows markup for the button in . If one of the Ellipse elements
inside the Canvas were to receive input, event routing would enable the Button,
Grid, Canvas, and Ellipse to receive the event, as shows.

Example. Handling events in a user interface tree
<Button PreviewMouseDown="PreviewMouseDownButton"
MouseDown="MouseDownButton">
<Grid PreviewMouseDown="PreviewMouseDownGrid"
MouseDown="MouseDownGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Canvas PreviewMouseDown="PreviewMouseDownCanvas"
MouseDown="MouseDownCanvas"
Width="20" Height="18" VerticalAlignment="Center">
<Ellipse PreviewMouseDown="PreviewMouseDownEllipse"
MouseDown="MouseDownEllipse"
x:Name="myEllipse"
Canvas.Left="1" Canvas.Top="1" Width="16" Height="16"
Fill="Yellow" Stroke="Black" />

A routed event can either be bubbling, tunneling, or direct. A bubbling event starts by
looking for event handlers attached to the target element that raised the event, and
then looks at its parent and then its parent’s parent, and so on until it reaches the
root of the tree; this order is indicated by the numbers in . A tunneling
event works in reverse—it looks for handlers at the root of the tree first and works its
way down, finishing with the originating element.
Direct events work like normal .NET events: only handlers attached directly to the
originating element are notified—no real routing occurs. This is typically used for
events that make sense only in the context of their target element. For example, it
would be unhelpful if mouse enter and leave events were bubbled or tunneled—the
parent element is unlikely to care about when the mouse moves from one child element
to another. At the parent element, you would expect “mouse leave” to mean “the
mouse has left the parent element,” and because direct event routing is used, that’s
exactly what it does mean. If bubbling were used, the event would effectively mean
“the mouse has left an element that is inside the parent, and is now inside another element
that may or may not be inside the parent,” which would be less useful.

Friday, 18 October 2013

WPF GRID

WPF GRID

Consider the document Properties dialog from Internet Explorer .
Notice how the main area of the form is arranged as two columns. The column on the
left contains labels, and the column in the middle contains information.

Achieving this kind of layout with any of the panels we’ve looked at so far is difficult,
because they are not designed with two-dimensional alignment in mind. We
could try to use nesting—Example 3-6 shows a vertical StackPanel with three rows,
each with a horizontal StackPanel.

The result, is not what we want at all. Each row has been
arranged independently, so we don’t get the two columns we were hoping for.
The Grid panel solves this problem. Rather than working a single row or a single column
at a time, it aligns all elements into a grid that covers the whole area of the
panel. This allows consistent positioning from one row to the next. Example 3-7
shows the same elements as Example 3-6, but arranged with a Grid rather than
nested StackPanel elements.
Example . Ineffective use of StackPanel
<StackPanel Orientation="Vertical" Background="Beige">
<StackPanel Orientation="Horizontal">
<TextBlock>Protocol:</TextBlock>
<TextBlock>HyperText Transfer Protocol</TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock>Type:</TextBlock>
<TextBlock>HTML Document</TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock>Connection:</TextBlock>
<TextBlock>Not Encrypted</TextBlock>
</StackPanel>
</StackPanel>


The Grid needs to know how many columns and rows we require, and we indicate
this by specifying a series of ColumnDefinition and RowDefinition elements at the
start. This may seem rather verbose—a simple pair of properties on the Grid itself
might seem like a simpler solution. However, you will often need to control the characteristics
of each column and row independently, so in practice, it makes sense to
have elements representing them.
Notice that each element in the grid has its column and row specified explicitly using
attached properties. This is mandatory—without these, everything ends up in column
0, row 0. (Grid uses a zero-based numbering scheme, so 0,0 corresponds to the
top-left corner.)

This default “one size fits all” behavior is useful when you want all the items in the
grid to be the same size, but it’s not what we want here. It would make more sense
for the column on the left to be wide enough to contain the labels, and for the column
on the right to be allocated the remaining space. Fortunately, the Grid provides
a variety of options for managing column width and row height.


Grid, Element Order, and Z Order

You might be wondering why the Grid doesn’t simply put items into the grid in the order
in which they appear; this would remove the need for the Grid.Row and Grid.Column
attached properties. However, grids do not necessarily have exactly one element per cell.
Grid cells can be empty. If the grid’s children simply filled the cells in order, you would
need to provide placeholders of some kind to indicate blank cells. But because elements
indicate their grid position, you can leave cells empty simply by providing no
content for those cells.
Elements may span multiple cells, by using the Grid.RowSpan and Grid.ColumnSpan
attached properties.
Cells can also contain multiple elements. In this case, the order in which the relevant
elements are listed in the markup determines which appears “on top.” Elements that
appear later in the document are drawn over those that appear earlier. The order in
which overlapping elements are drawn is usually referred to as the Z order. This is
because the x- and y-axes are traditionally the ones used for drawing on-screen, so the
z-axis, representing the third dimension, “sticks out” of the screen. This makes it the
logical axis to represent how overlapping elements stack up on top of one another.
In general, panels that allow their children to overlap (e.g., Grid and Canvas) rely on the
order in which elements appear in the XAML to determine the Z order. However, you
can override this: the attached Panel.ZIndex property allows the Z order to be specified

explicitly.

Saturday, 7 September 2013

WPF Layout Basics

WPF Layout Basics

WPF provides a set of panels—special-purpose user interface elements whose job is to
arrange the elements they contain. Each individual panel type offers a straightforward
and easily understood layout mechanism. As with all WPF elements, layout objects
can be composed in any number of different ways, so although each individual panel
type is fairly simple, the flexible way in which they can be combined makes for a very
powerful layout system. And you can even create your own layout element types
should the built-in ones not meet your needs.
Table describes the main panel types built into WPF.* Whichever panel you use,
the same basicrule always applies: an element’s position is always determined by the
containing panel. Most panels also manage the size of their children.


WPF StackPanel

StackPanel is a very simple panel that arranges its children in a row or a column. You
will not normally use StackPanel to lay out your whole user interface. It is most useful
for arranging small subsections. Example 3-1 shows how to build a simple search
user interface.
Figure 3-1 shows the results. As you can see, the UI elements have simply been
stacked vertically one after another. This example used the Margin property to space
the elements out a little. Most elements use a single number, indicating a uniform
margin all around. The Button uses a pair of numbers to specify different vertical and
Table 3-1. Main panel types
Panel type Usage
StackPanel Lays children out in a vertical or horizontal stack; extremely simple, useful for managing small-scale
aspects of layout.
WrapPanel Lays children out from left to right, moving onto a new line each time it fills the available width.
DockPanel Allocates an entire edge of the panel area to each child; useful for defining the rough layout of simple
applications at a coarse scale.
Grid Arranges children within a grid; useful for aligning items without resorting to fixed sizes and positions.
The most powerful of the built-in panels.
Canvas Performs no layout logic—puts children where you tell it to; allows you to take complete control of
the layout process.
UniformGrid Arranges children in a grid where every cell is the same size.

Example . StackPanel search layout
<StackPanel Background="#ECE9D8">
<TextBlock Margin="3">Look for:</TextBlock>
<ComboBox Margin="3"/>
<TextBlock Margin="3">Filtered by:</TextBlock>
<ComboBox Margin="3"/>
<Button Margin="3,5">Search</Button>
<CheckBox Margin="3">Search in titles only</CheckBox>
<CheckBox Margin="3">Match related words</CheckBox>
<CheckBox Margin="3">Search in previous results</CheckBox>
<CheckBox Margin="3">Highlight search hits (in topics)</CheckBox>
</StackPanel>

horizontal margins. This is one of several standard layout properties available on all
WPF elements, which are all described in the “Common Layout Properties” section,
There is one problem with this layout: the Search button is much wider than you
would normally expect a button to look. The default behavior of a vertical
StackPanel is to make all of the controls the same width as the panel. Likewise, a
horizontal StackPanel will make all of the controls the same height. For the ComboBox
controls, this is exactly what we want. For the TextBlock and CheckBox controls, it
doesn’t show that the controls have been stretched to be as wide as the panel,
because they look only as wide as their text makes them look. However, a Button’s
visuals always fill its entire logical width, which is why the button in Figure 3-1 is
unusually wide. (See the upcoming “Fixed Size Versus Size to Content” sidebar for
more details on how this process works.)
When an element has been given a fixed amount of space that is greater than
required by its content, the way in which the extra space gets used is determined by
the HorizontalAlignment and VerticalAlignment properties.
We can prevent the button from being stretched across the panel’s whole width by
setting its HorizontalAlignment property to Left:
<Button Margin="3,5" HorizontalAlignment="Left">Search</Button>
HorizontalAlignment determines an element’s horizontal position and width in situations
where the containing panel gives it more space than it needs. The default is
Stretch, meaning that if more space is available than the child requires, it will be
stretched to fill that space. The alternatives—Left, Right, and Center—do not
attempt to stretch the element; these determine where the element will be placed
within the excess space, allowing the element to use its natural width. Here we are
using Left, meaning that the control will have its preferred width, and will be aligned
to the left of the available space.
The preceding example used the default vertical orientation. StackPanel also supports
horizontal layout. Example  shows a StackPanel with its Orientation property set
to Horizontal.

Example  Horizontal StackPanel layout
<StackPanel Orientation="Horizontal">
<TextBlock>This is some text</TextBlock>
<Button>Button</Button>
<Button>Button (different one)</Button>
<CheckBox>Check it out</CheckBox>
<TextBlock>More text</TextBlock>
</StackPanel>

WPF WrapPanel

WrapPanel works just like a StackPanel until it runs out of space. If you provide a horizontal
WrapPanel with more children than will fit in the available width, it will
arrange its content in a way similar to how a word processor lays out words on a
line. It puts the children in a row from left to right until it runs out of space, at which
point it starts on the next line.

WrapPanel is very simple to use. Just as with a StackPanel, you add a sequence of children,
as shows.

<WrapPanel Background="Beige">
<Button>One</Button>
<Button>Two</Button>
<Button>Three</Button>
<Button>Four</Button>
<Button>Five</Button>
<Button>Six</Button>
<Button>Seven</Button>
<Button>Eight</Button>
</WrapPanel>

WrapPanel also offers an Orientation property. Setting this to Vertical will arrange
the children in a sequence of vertical stacks, a layout style very similar to Windows
Explorer’s “List” view.
WrapPanel and StackPanel really are useful only for small-scale layout. You will need
to use a more powerful panel to define the overall layout of your application, such as
DockPanel.

WPF DockPanel


DockPanel is useful for describing the overall layout of a simple user interface. You
can carve up the basic structure of your window using a DockPanel, and then use the
other panels to manage the details.
A DockPanel arranges each child element so that it fills a particular edge of the panel.
If multiple children are docked to the same edge, they simply stack up against that
edge in order. By default, the final child fills any remaining space not occupied by
controls docked to the panel’s edges.
Example  shows a simple DockPanel-based layout. Five buttons have been added
to illustrate each option. Notice that four of them have a DockPanel.Dock attribute
applied. This property is defined by DockPanel to allow elements inside a DockPanel
to specify their position. DockPanel.Dock is an attachedproperty (as described in the
upcoming sidebar, “Attached Properties and Layout”).

<DockPanel>
<Button DockPanel.Dock="Top">Top</Button>
<Button DockPanel.Dock="Bottom">Bottom</Button>
<Button DockPanel.Dock="Left">Left</Button>
<Button DockPanel.Dock="Right">Right</Button>
<Button>Fill</Button>
</DockPanel>

Elements never overlap in a DockPanel, so each successive child only gets to use space
not already used by the previous children. By default, the final child takes all of the
remaining space, but if you would prefer to leave a blank space in the middle, you
can set the LastChildFill attribute of the DockPanel to False. (It defaults to True.)
The final child will dock to the left by default, leaving the center empty.

Sunday, 1 September 2013

WPF Application Deployment

WPF Application Deployment

For the purposes of demonstration, let’s build something vital for procrastinators the
world over: an application to generate excuses. The application was started with the
“Windows Application (WPF)” project template in Visual Studio 2005 and was
implemented with some very simple code. When you run it, it gives you an excuse
from its vast database.

Simple Publishing


For anyone to use this wonderful application, it must be published. The simplest
way to publish your WPF application is by right-clicking on the project in the Solution
Explorer and choosing the Publish option, which will bring up the first page of
the Publish Wizard. It asks you to choose where you’d like to deploy your application, including
to the disk, to a network share, to an FTP server, or to a web site. By default, the
Publish Wizard will assume you want to publish to the Publish subdirectory of your
project directory. Clicking the Next button.Because we’ve chosen to publish to something besides a web site, the Publish Wizard
wants to know how users will access your published application—in other
words, from a URL, from a UNC path, or from some optical media. (If you choose to
publish to a web site, the only way to access the application is from a URL, so it
won’t bother to ask.) We’d like to test web deployment, so we pick that option and
leave the default URL alone. Clicking Next.
For WPF applications, lets us choose whether we’d like this application to
be made available online (when the computer is able to connect to the application’s
URL) as well as offline (when the computer can’t connect to the URL), or whether
you’d like the application to be only available online. These two options correspond
to the ClickOnce terms locally installed and online only, respectively.
It reminds us what we get with a locally installed ClickOnce application (i.e.,
the application will appear in the Start menu and in the Add or Remove Programs
Control Panel). Clicking Finish causes Visual Studio to publish the application to the
filesystem, including a publish.htm file that you can use to test deployment. If you
happen to have an IIS application set up in the same folder to which Visual Studio
publishes, it will launch the publish.htm file for you, 
For simple needs, this is the complete experience for publishing a WPF ClickOnce
locally installed application.

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.

Wednesday, 31 July 2013

How XAML Markup Extensions Works

XAML Markup Extensions

Before we take a look at the results of our data binding, let’s take a moment to discuss
XAML markup extensions, which is what you’re using when you set an attribute
to something inside of curly braces (e.g., Text="{Binding Path=Name}"). Markup
extensions add special processing to XAML attribute values. For example, this:
<TextBox Text="{Binding Path=Name}" />
is just a shortcut for this (which you’ll recognize as the property element syntax):
<TextBox.Text>
<Binding Path="Name" />
</TextBox.Text>


Data Templates


With the data binding markup syntax explained, let’s turn back to our example data
binding application, which so far doesn’t look quite like what we had in mind,It’s clear that the data is making its way into the application, because the currently
selected name and nickname are shown for editing. The problem is that, unlike the
TextBox controls, which were each given a specific field of the Nickname object to show,
the ListBox is expected to show the whole thing. Lacking special instructions, it’s calling
the ToString method of each object, which results in only the name of the type. To
show the data, we need to compose a data template.

Example . Using a data template
<ListBox
ItemsSource="{Binding}"
IsSynchronizedWithCurrentItem="True">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock Text="{Binding Path=Name}" />:
<TextBlock Text="{Binding Path=Nick}" />
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

A data template is a set of elements that should be inserted somewhere. In our case,
we are specifying a data template to be inserted for each listbox item by setting the
ItemTemplate property. In Example, we’ve composed a data template from a text block that flows together two other text blocks, each bound to a property on a
Nickname object separated by a colon, At this point, we’ve got a completely data-bound application. As data in the collection
or the individual objects changes, the UI will be updated, and vice versa. However,
there is a great deal more to say on this topic, including binding to XML and
relational data, master-detail binding, and hierarchical binding.


Dependency Properties



Although our data source Nickname object made its data available via standard .NET
properties, we need something special to support data binding on the target element.
Even though the TextContent property of the TextBlock element is exposed
with a standard property wrapper, in order for it to integrate with WPF services like
data binding, styling, and animation, it also needs to be a dependency property. A
dependency property provides several features not present in .NET properties,
including the ability to inherit its value from a container element, provide for objectindependent
storage (providing a potentially huge memory savings), and change
tracking.
Most of the time, you won’t have to worry about dependency properties versus .NET
properties.

Resources

Resources are named chunks of data defined separately from code and bundled with
your application or component. .NET provides a great deal of support for resources,
a bit of which we already used when we referenced tom.png from our XAML button
earlier in this chapter. WPF also provides special support for resources scoped to elements
defined in the tree.
As an example, let’s declare some default instances of our custom Nickname objects in
XAML 
Notice the Window.Resources, which is property element syntax to set the Resources
property of the Window1 class. Here we can add as many named objects as we like,
with the name coming from the Key attribute and the object coming from the XAML
elements (remember that a XAML element is just a mapping to .NET class names).
In this example, we’re creating a Nicknames collection named names to hold three
Nickname objects, each constructed with the default constructor, and then setting
each of the Name and Nick properties.
Also notice the use of the StaticResource markup extension to reference the names
resource as the collection to use for data binding. With this XAML in place, our window
construction reduces to the code shown in Example 

Example . Declaring objects in XAML
<!-- Window1.xaml -->
<Window ... xmlns:local="clr-namespace:DataBindingDemo" />
<Window.Resources>
<local:Nicknames x:Key="names">
<local:Nickname Name="Don" Nick="Naked" />
<local:Nickname Name="Martin" Nick="Gudge" />
<local:Nickname Name="Tim" Nick="Stinky" />
</local:Nicknames>
</Window.Resources>
<DockPanel DataContext="{StaticResource names}">
<TextBlock DockPanel.Dock="Top" Orientation="Horizontal">
<TextBlock VerticalAlignment="Center">Name: </TextBlock>
<TextBox Text="{Binding Path=Name}" />
<TextBlock VerticalAlignment="Center">Nick: </TextBlock>
<TextBox Text="{Binding Path=Nick}" />
</TextBlock>
...
</DockPanel>
</Window>

Example . Finding a resource in code
public partial class Window1 : Window {
Nicknames names;
public Window1( ) {
InitializeComponent( );
this.addButton.Click += addButton_Click;
// get names collection from resources
this.names = (Nicknames)this.FindResource("names");
// no need to make data available for binding here
//dockPanel.DataContext = this.names;
}
void addButton_Click(object sender, RoutedEventArgs e) {
this.names.Add(new Nickname( ));
}
}

Now instead of creating the collection of names, we can pull it from the resources 
with the FindResource method. Just because this collection was created in XAML 
doesn’t mean that we need to treat it any differently than we treated it before, which 
is why the Add button event handler is the exact same code. Also, there’s no need to 
set the data context on the dock panel because that property was set in the XAML. 
For the full scoop on resources, including resource scoping and lookup, static and 
dynamic binding to resources, and using resources for theming and skinning,


Wednesday, 3 July 2013

How to Edit XAML

Editing XAML

Now that we’ve seen the wonder that is declarative UI description in XAML, you
may wonder, “Do I get all the fun of editing the raw XML, or are there some tools
that can join in the fun, too?” The answer is “sort of.” For example, if you’ve got the
.NET Framework 3.0 extensions for Visual Studio 2005 (the same extensions that give
you the WPF project templates in VS05), you will have a visual editor for XAML files
that works very similarly to the built-in Windows Forms Designer. It will trigger by
default when you double-click a file in the Solution Explorer, or you can right-click on a XAML file in the Solution Expression and choose Open With. One of the options
offered will be “WPF Designer (Cider)” (where “Cider” is the codename for the WPF
Designer still under development). The WPF Designer allows for drag-and-drop-style
construction of XAML files with elements from the Toolbox and setting properties in
the property browser. In addition, you can see the XAML as the designer makes
changes, and in fact, you can make changes in the XAML view itself and see those
reflected in the designer. Figure 1-6 shows the WPF Designer in action.

WPF itself was created as a unified presentation framework, meant to enable building
Windows applications with the best features from existing Windows application
practice and existing web application practice. One of the nice things that web applications
provide is a single window showing the user one page of content/functionality
at a time, allowing for navigation among the pages. For some applications, including
Internet Explorer, the shell Explorer, Microsoft Money, and a bunch of Control Panel
applets, this is thought to be preferable to the more common Windows application
practice of showing more than one window at a time.

To enable more of these kinds of applications, WPF provides the page, which is the
unit of navigation in an XML Browser Application (XBAP). Instead of setting an
application’s StartupUri to a XAML file that defines a window, we point an XBAP’s
StartupUri at a XAML file that defines a page.

Example . Starting with a Page instead of a Window
<!-- App.xaml -->
<Application
x:Class="MyFirstXbapApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Page1.xaml" />

Example . A sample page
<!-- Page1.xaml -->
<Page
x:Class="MyFirstXbapApp.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowTitle="Page1">
<TextBlock FontSize="36">
Check out <Hyperlink NavigateUri="page2.xaml">page 2</Hyperlink>, too.
</TextBlock>
</Page>
// Page1.xaml.cs
...
namespace MyFirstXbapApp {
public partial class Page1 : System.Windows.Controls.Page {
public Page1( ) {
InitializeComponent( );
}
}
}

The primary way to allow the user to navigate in an XBAP is via the Hyperlink element,
setting the NavigateUri to a relative URL of another XAML page in the project.

As you might imagine, there are many more topics to discuss to make your XBAPs
integrate with the browser and still provide the rich functionality we expect from
WPF applications. In addition, you can have any number of navigation windows in
your standalone WPF applications.


XAML Property Element Syntax

Although setting the Content property as an XML attribute works just fine for specifying
a string as a property, it doesn’t work at all well for specifying a subelement,
like the image example. For this reason, XAML defines the property element syntax,
which uses nested Element.Property elements for specifying objects as property values.
For instance, Example shows the property element syntax for the string setting
of a button’s content.


Example . Property element syntax with a string
<Button Width="100" Height="100">
<Button.Content>Hi</Button.Content>
</Button>


Example . Property element syntax with an image
<Button Width="100" Height="100">
<Button.Content>
<Image Source="tom.png" />
</Button.Content>
</Button>


Example . You can’t have multiple things in a ContentControl
<Button Width="100" Height="100">
<!-- WARNING: doesn't work! -->
<Button.Content>
<TextBlock>Tom: </TextBlock>
<Image Source="tom.png" />
</Button.Content>
</Button>

Sunday, 30 June 2013

What is XAML

XAML

XAML is an XML-based language for creating and initializing .NET objects. It’s used
in WPF as a human-authorable way of describing the UI, although you can use it for
a much larger range of CLR types than just those in WPF. Example 1-8 shows how
we declare the UI of our Window-derived class using XAML.

Example 1-8. Declaring a Window in XAML
<!-- Window1.xaml -->
<Window
x:Class="MyFirstWpfApp.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Hello, WPF">
<Button
x:Name="button"
Width="200"
Height="25"
Click="button_Click">Click me, baby, one more time!</Button>
</Window>

The root element, Window, is used to declare a portion of a class, the name of which is
contained in the Class attribute from the XAML XML namespace (declared with a
prefix of “x” using the “xmlns” XML namespace syntax). The two XML namespace
declarations pull in two commonly used namespaces for XAML work, the one for
XAML itself (the one with the “x” prefix) and the one for WPF (which we’ve
declared as the default for this XML file). You can think of the XAML


Example . C# equivalent of XAML from Example 1-8 (continued)
void InitializeComponent( ) {
// Initialize Window1
this.Title = "Hello, WPF";
// Initialize button
button = new Button( );
button.Width = 200;
button.Height = 25;
button.Click += button_Click;
this.AddChild(button);
     }
   }
 }

XAML was built to be as direct a mapping from XML to .NET as possible. Generally,
a XAML element is a .NET class name and a XAML attribute is the name of a
property or an event on that class. This makes XAML useful for more than just WPF
classes; pretty much any old .NET class that exposes a default constructor can be initialized
in a XAML file.
Notice that we don’t have the definition of the click event handler in this generated
class. For event handlers and other initializations and helpers, a XAML file is meant
to be matched with a corresponding code-behind file, which is a .NET language code
file that implements behavior in code “behind” the look defined in the XAML. Traditionally,
this file is named with a .xaml.cs extension and contains only the things not
defined in the XAML. With the XAML from Example 1-8 in place, we can reduce
our single-buttoned main window code-behind file to the code in Example 1-10.

Example . C# code-behind file
// Window1.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
namespace MyFirstWpfApp {
public partial class Window1 : Window {
public Window1( ) {
InitializeComponent( );
}
void button_Click(object sender, RoutedEventArgs e) {
MessageBox.Show(...);
  }
 }
}

Notice the partial keyword modifying the Window1 class, which signals to the compiler
that the XAML-generated class is to be paired with this human-generated class to form
one complete class, each depending on the other. The partial Window1 class defined in
XAML depends on the code-behind partial class to call the InitializeComponent
method and to handle the click event. The code-behind class depends on the partial
Window1 class defined in XAML to implement InitializeComponent, thereby providing
the look of the main window (and related child controls).
Further, as mentioned, XAML is not just for visuals. For example, nothing is stopping
us from moving most of the definition of our custom MyApp class into a XAML
file (Example 1-11).

This reduces the MyApp code-behind file to the event handler in Example 1-12.
You may have noticed that we no longer have a Main entry point to create the
instance of the application-derived class and call its Run method. That’s because WPF
has a special project setting to specify the XAML file that defines the application
class, which appears in the msbuild project file.

Example . Declaring an application in XAML
<!-- MyApp.xaml -->
<Application
x:Class="MyFirstWpfApp.MyApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="AppStartup">
</Application>
Example 1-12. Application code-behind file
// MyApp.xaml.cs
using System;
using System.Windows;
namespace MyFirstWpfApp {
public partial class MyApp : Application {
void AppStartup(object sender, StartupEventArgs e) {
Window window = new Window1( );
window.Show( );
  }
 }
}

Friday, 21 June 2013

Start with WPF

Window Presentation Format (WPF)


WPF is a completely new presentation framework, integrating the capabilities of
many frameworks that have come before it, including User, GDI, GDI+, and HTML,
as well as being heavily influenced by toolkits targeted at the Web, such as Adobe
Flash, and popular Windows applications like Microsoft Word. This chapter will
give you the basics of WPF from scratch, and then a whirlwind tour of the things
you’ll read about in detail in this Blog.

Building Applications In WPF


Building this application (Example 1-2) is a matter of firing off the C# compiler from
a command shell with the appropriate environment variables.* (The command line
here has been spread across multiple lines for readability, but you need to put it all
on one line.)

Example 1. Building a WPF application manually
C:\1st> csc /target:winexe /out:.\1st.exe
/r:System.dll
/r:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll"
/r:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\PresentationCore.dll"
/r:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\
PresentationFramework.dll"
MyApp.cs

Here, we’re telling the C# compiler that we’d like to create a Windows application
(instead of a Console application, which we get by default), putting the result, 1st.exe,
into the current folder, referencing the three main WPF assemblies (WindowsBase,
PresentationCore, and PresentationFramework), along with the core .NET System
assembly, and compiling the MyApp.cs source file.
Running the resulting 1st.exe produces the world’s lamest WPF application.

Example 2. A minimal msbuild project file
<!-- 1st.csproj -->
<Project
DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputType>winexe</OutputType>
<OutputPath>.\</OutputPath>
<Assembly>1st.exe</Assembly>
</PropertyGroup>
<ItemGroup>
<Compile Include="MyApp.cs" />
<Reference Include="System" />
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<Import Project="$(MsbuildBinPath)\Microsoft.CSharp.targets" />

</Project>

The msbuild tool is a .NET 2.0 command-line application that understands XML
files in the form shown in Example 2. The file format is shared between msbuild
and Visual Studio 2005 so that you can use the same project files for both commandline
and integrated development environment (IDE) builds. In this .csproj file (which
stands for “C# Project”), we’re saying the same things we said to the C# compiler—
in other words, we’d like a Windows application, we’d like the output to be 1st.exe
in the current folder, and we’d like to reference the System assembly and the main
WPF assemblies while compiling the MyApp.cs file. The actual smarts of how to turn
these minimal settings into a compiled .NET application are contained in the .NET

2.0 Microsoft.CSharp.targets file that’s imported at the bottom of the file.


Example 3. Building using msbuild (continued)
Target CoreCompile:
C:\Windows\Microsoft.NET\Framework\v2.0.50727\Csc.exe /noconfig /nowarn:1701
,1702 /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0
\PresentationCore.dll" /reference:"C:\Program Files\Reference Assemblies\Microso
ft\Framework\v3.0\PresentationFramework.dll" /reference:C:\Windows\Microsoft.NET
\Framework\v2.0.50727\System.dll /reference:"C:\Program Files\Reference Assembli
es\Microsoft\Framework\v3.0\WindowsBase.dll" /debug+ /out:obj\Debug\1st.exe /tar
get:winexe MyApp.cs
Target _CopyFilesMarkedCopyLocal:
Copying file from "C:\Program Files\Reference Assemblies\Microsoft\Framework
\v3.0\PresentationCore.dll" to ".\PresentationCore.dll".
Copying file from "C:\Program Files\Reference Assemblies\Microsoft\Framework
\v3.0\System.Printing.dll" to ".\System.Printing.dll".
Copying file from "C:\Program Files\Reference Assemblies\Microsoft\Framework
\v3.0\PresentationCore.xml" to ".\PresentationCore.xml".
Copying file from "C:\Program Files\Reference Assemblies\Microsoft\Framework
\v3.0\System.Printing.xml" to ".\System.Printing.xml".
Target CopyFilesToOutputDirectory:
Copying file from "obj\Debug\1st.exe" to ".\1st.exe".
1st -> C:\1st\1st.exe
Copying file from "obj\Debug\1st.pdb" to ".\1st.pdb".
Build succeeded.
0 Warning(s)
0 Error(s)

Time Elapsed 00:00:04.15

WPF Applications

A real WPF application is going to need more than a message box. WPF applications
have an instance of the Application class from the System.Windows namespace.
The Application class provides methods like Run for starting the application, events
like Startup and SessionEnding for tracking lifetime, and properties like Current,
ShutdownMode, and MainWindow for finding the global application object, choosing
when it shuts down, and getting the application’s main window. Typically, the

Application class serves as a base for custom application-wide data and behavior.