WPF Architecture

The WPF architecture consists of two frameworks, one managed and one unmanaged. The managed API


is referred to as the presentation framework and provides all of the functionality you need to build WPF

applications, such as controls, layout, data binding, and visuals. The unmanaged API is referred to as the 

Media Integration Layer (MIL) and provides the low-level functionality of the WPF architecture, such as

composition and rendering. Although the unmanaged functionality is not publicly exposed, it is the

heart of the WPF presentation engine. All pixel rendering happens in the MIL.

This section covers the following:

Architecture

Core subsystems

Threading model

Figure 11-1 illustrates the various components that make up the WPF architecture.

Taking a bottom-up approach, we can see that underlying WPF are DirectX, User32, display drivers

(WDDM and XPDM), and the graphics card. All software rendering in WPF will ultimately end up being

rendered by the graphics card. The WDDM and XPDM drivers work closely with your graphics card. If

you are running Windows Vista then your system will use the new Windows Display Driver Model

(WDDM) driver. If you are using XP, your system will use the XP Driver Model (XPDM). There is not

necessarily a requirement when it comes to the graphics card you use; WPF will scale based on the

amount of video memory your graphics card contains.

Sitting just above the display drivers are the DirectX and User32 libraries. DirectX is used to render 2D,

3D, text, or animation, utilizing the full power of the graphics processing unit (GPU). User32 manages

the windows on the desktop. These components remain unchanged in WPF, but they provide the foundation

upon which WPF builds.

The Media Integration Layer (MIL) resides just above User32 and DirectX. The MIL consists of the WPF

unmanaged composition system (don’t confuse this with the composition model WPF uses in which elements

contain other elements) and an unmanaged rendering engine, which talks to DirectX. The WPF

composition and rendering engine are central components of the WPF architecture. The MIL analyzes an

Presentation Framework

Presentation Core

Media Integration Layer (MIL)

WPF

Visual System

Composition System

Render Engine

DirectX

Graphics Card

User 32

WDDM XPDM

Message

Transport

application’s visual data in order to render the user interface and is ultimately responsible for painting

pixels on the screen. The MIL doesn’t work alone; it renders pixels with the help of DirectX. Because

DirectX is a 3D rendering engine, the MIL translates the nodes on the composition tree into data that is

consumable by DirectX.

The Presentation Core sits between the MIL and the presentation framework and is home to the WPF

visual system. The visual system provides classes that represent visuals in WPF, which are the elements

that make up an application’s visual tree, ultimately representing the application’s UI. The visual system

communicates with the MIL through a message transport, which provides a two-way messaging system

through which the visual system and MIL may communicate rendering data and instructions to ultimately

get pixels on the screen.

The presentation framework sits at the top of the WPF architecture stack and is the primary API you will

use to create WPF applications. The presentation framework provides application support, such as controls,

layout, data binding, and styling to visuals located in the visual system. We discuss the components

and classes that make up the presentation framework in the next section.

Core Subsystems

Let’s review what we referred to in the introduction as the core subsystems of the WPF architecture: the

visual system, message transport, and composition system, which were introduced in Chapter 1:

The visual system is the subsystem through which applications access the core presentation services

available through WPF.

The visual system creates a visual tree, which contains all an application’s visual elements and

rendering instructions.

The visual system communicates via the message transport with the underlying composition

system to get pixels rendered to the screen.

The composition system is an unmanaged subsystem that receives rendering instructions from

the managed visual system, and turns those instructions into data consumable by DirectX.

The message transport provides a two-way communication channel that supports messaging

between the visual system and the composition system.

The Visual System

As you learned in Chapter 1, the visual system is the managed subsystem through which applications

access the core presentation services available through WPF. The visual system is where an application’s

visual tree resides. The visual tree is a hierarchical data structure that represents all of an application’s

visual elements and drawing instructions for a given window or page. These drawing instructions are

what the composition and rendering engine require in order to paint pixels to the screen. The visual tree

is used by our application to manage its GUI. This tree allows for programmatic manipulation of visual

elements. Many of the WPF subsystems, such as the input and event subsystems, use this tree.

The visual system does not actually render anything. It simply defines and manages what will be rendered.

When an application needs to render its UI to the screen, or when an update to its UI needs to be

made, it passes its visual data, one element at a time, down to the composition system via the message

transport channel. The composition system will compose its own tree, called the composition tree, and

then request rendering to be performed by the rendering engine. Because the visual system lives on a

separate thread from the MIL systems, the application does not have to wait for rendering operations to

complete in order to continue processing business logic. This is referred to as a retained mode graphics

model.

The WPF retained mode graphics model (as shown in Figure 11-2) breaks from the traditional Win32

immediate mode graphics model, in which painting the screen is the responsibility of the application.

With either model, when windows are moved or resized, the area behind the window that is exposed

becomes invalid, requiring it to be repainted. Under Win32, when a region of the screen is invalidated, a

WM_PAINT message is sent to the application from the Windows OS, and it is the responsibility of the

application to repaint the invalidated surface. This often results in brief trails or blurriness of the screen

while the re-painting takes place. The key concept in an immediate mode graphics system is that the

application is itself responsible for managing its graphics data, rendering this data, and responding to

system messages to refresh or repaint its client area.

Figure 11-2

With the retained mode graphics model (as shown in Figure 11-3), WPF applications are no longer

required to manage their own rendering. Applications merely manage their visual data and then pass

this data along to the MIL. The MIL will handle the rest of the work, leaving an application free to continue

processing input commands and executing code. Furthermore, the MIL can cache and optimize the

graphical data it manages, allowing for greater performance on the desktop. The key concept in a

retained mode graphic system is that the application merely defines and manages its graphics data,

passes this data to the MIL essentially offloading the actual rendering work, and then only sends edits as

necessary to the MIL when UI changes are required.

Figure 11-3

Application

WPF WM_PAINT Windows

Application WM_PAINT

Invalidate

Windows

GDI

In addition to using a retained mode graphics model, WPF also implements a new painting algorithm.

Objects that overlap each other are painted to the screen from back to front. This allows WPF to apply

effects, such as transparency, to objects. The key concept here is that more than one object may affect any

given pixel.

The Composition System

Before you explore the composition system, we need to point out that, although we have talked about

the visual data being passed to the composition system for rendering, the composition tree used by the

composition system is not the same visual tree used by the application. The primary differences between

them are as follows:

The visual tree is managed; the composition tree is unmanaged.

The visual tree lives on the UI thread; the composition tree lives on the render thread.

The visual tree is used by the application for managing its GUI and supporting subsystems,

such as input and events; the composition tree is used strictly for rendering.

The visual tree represents all elements that make up the application’s UI; the composition tree

contains only the elements that will be visible on the screen.

The composition system is responsible for composing all of an application’s visible visual elements to

the screen. The composition system manages an element tree, called the composition tree, for composing

the application’s GUI. The composition tree is an unmanaged tree containing only nodes representing

elements that will be visible on the screen.

The composition system lives in the MIL on the render thread, and there is only one render thread per

WPF process. The composition system runs on the render thread, in the background, waiting to receive

visual data from the visual system via the message transport. Once the visual data is received, the composition

system will modify its composition tree as necessary, process the drawing instructions for each

element, and calculate pixels. Render data is then passed to the rendering engine of the MIL, where it is

translated and communicated down to DirectX for painting pixels.

Once the composition system has prepared the visual data for rendering, it passes that data to the render

engine of the MIL. The render engine uses DirectX to implement hardware-based rendering. This model

takes full advantage of the power of the graphics card available in most modern computers. DirectX utilizes

a computer’s graphical processing unit (GPU) rather than the onboard CPU for rendering graphics.

This decreases the load on the CPU, allowing it to focus on OS and application level commands, rather

than on rendering pixels to the screen. The net effect is a rendering process handled through hardware

rather than software.

DirectX does not know how to render shapes such as square, rectangle, or ellipse. DirectX understands

rendering in terms of triangles. The render engine must translate shapes into triangles that DirectX can

understand. The process of converting shapes to triangles is called tessellation.

The WPF composition system is a vector-based composition engine. The vector-based composition system

creates images on the screen composed from primitives. Primitives are defined as points, lines, polygons,

and curves, which are all geometric shapes. This is different from Win32, which used fixed-size raster

graphics. Raster graphics are composed from pixels, which are not scalable. Think about the effects of

resizing a bitmap in an application. As the scale of the image increases, the quality degrades. Vectors, on

the other hand, are highly scalable based on the fact they are constructed of primitives. What this means is

that vector graphics can re-size without loss of graphic quality, regardless of screen resolution.

The Message Transport

The message transport provides a two-way communication channel across the threading boundaries of

the visual system, which lives on the UI thread, and the composition system, which lives on the render

thread. The message transport consists of two parts: a transport and a channel. The transport is a communication

mechanism. The channel sits on top of the transport and allows an application to place

resources, such as Brush or Rectangle, onto the transport.

Using this communication channel, visual data can be passed from the visual system to the composition

system for rendering. When a change or edit occurs in the visual system, the visuals created, removed,

or affected are passed individually across this channel to the composition system. This has a positive

impact on performance, as the entire visual tree is not transferred every time an edit occurs.

In the two-way communication process, communication from the composition system to the visual system

is limited and primarily involves simply reporting errors.

When applications are running locally, this channel is really just a pipe accessing shared memory

because the two threads are running in the same process. The composition system can access the memory

and construct its own copy of the tree. In a remote scenario, such as Terminal Services, data is not

shared; rather, it is passed along in a Terminal Services Envelope.

Now that you’ve reviewed the core systems, you can understand the following pseudo-logic example

for how rendering occurs in WPF.

An Ellipse is added to the application’s UI, becoming part of the visual tree.

The application sends a visual element (the Ellipse) across the message transport to the composition

system (UI thread work is complete; render thread work starts).

The composition system creates its own composition tree from the visual it receives.

The composition system tells the rendering engine to “Draw an Ellipse.”

The rendering engine prepares the data for DirectX by tessellating the Ellipse.

The rendering engine tells DirectX to render and passes along the tessellated data.

DirectX issues the data to the display driver (WDDM or XPDM).

The display driver works with the graphics card to render pixels on the screen.

WPF Threading Model

WPF applications are single-threaded applications (STA). An application may create one or many UI

threads via the WPF Dispatcher object, but each UI thread, individually, is single-threaded. The visual

system lives on the UI thread, and a WPF application essentially owns this thread. When the visual system

needs to render its UI, it will pass visual elements to the composition system of the MIL, located on

the render thread. There is only one render thread per WPF process.

The threading model and separation of visual system and composition system responsibilities is an important

concept in WPF architecture. Because a WPF application does not live on the same thread that performs

rendering, the application does not have to wait for rendering to complete in order to continue processing.

The separation of responsibilities by thread provides for some unique functionality. In WPF, the separation

of UI and render threads and the communication via the message transport provides a flexible

model that applications, such as Terminal Services or Remote Desktop, can exploit. A remote server running

an application will manage the UI thread. Using the message transport, the remote server application

can simply send visual data to the client machine where the client’s render thread can do the actual

rendering. This requires far less bandwidth than sending bitmaps across the wire, providing for

increased performance on the client machine.

Desktop Window Manager

The Desktop Window Manager (DWM) is new in Windows Vista. The DWM is the component responsible

for providing the incredible new visual experience Vista provides. Why are we discussing the DWM

in a book about WPF you ask? Well, because the DWM utilizes the same composition system of the MIL

layer that our WPF applications utilize and, therefore, is a testament to the power of WPF.

The DWM presents a fundamental change in the way pixels are rendered to the screen from previous

Windows display models. This fundamental change is rooted in a concept known as desktop composition,

which is the process of composing the entire visible screen from all running application windows.

Under the hood, the DWM manages a visual tree just like WPF applications, but conceptually it’s a

higher level tree that represents all components that make up the visible desktop.

Prior to WPF, Vista, and the DWM, applications managed the rendering of their window client areas

directly. These applications would write directly to a buffer used by the video card to render UI. With

WPF, applications are no longer required to do this. Rather, the WPF composition system writes the

application’s client area to an off-screen buffer and the DWM takes over from there. The DWM is responsible

for composing off-screen buffers for all running applications and handing them off to the video

card for rendering.

The division of rendering responsibilities between the application and DWM provides an opportunity

for the DWM to transform windows before rendering. For instance, the DWM will apply Vista themes,

such as the new Vista Aero or Glass themes. The DWM can also optimize pixel resolution, taking advantage

of high resolution monitors when available.

UI Thread

Visual System

WPF Threading Model

Render Thread

Composition

System

Message

Transport

Together, the WPF composition system and DWM provide a far richer user experience. Gone are the

days of window trails when moving windows on the desktop, and here now are the days of transparent

windows and thumbnail window viewing.

The WPF Framework

The WPF framework provides a rich programming model you can use to develop next-generation WPF

applications. We have explored many of the classes that make up the framework throughout this book.

The WPF framework provides classes for styling controls, layout, input, and event routing; using data

binding; drawing 2D and 3D shapes; creating animations; accessing and manipulating the visual tree;

and there’s plenty more. All of this is exposed to you through a familiar programming model because

WPF is built on top of the .NET 2.0 Framework.

The WPF framework is very extensive. There are many ways one can slice and dice the framework in an

effort to describe it. One can look at each subsystem individually and the classes that support it, for

instance the property system or event system. One can break it into presentation core and presentation

framework layers and describe important classes in each. In this section, we explore the individual classes

that make up the inheritance hierarchy and describe the subsystems supported at each step along the way.

Figure 11-5 illustrates the inheritance hierarchy of the core WPF framework classes.

Figure 11-5

Object

DispatcherObject DependancyProperty

Presentation Core

FrameworkElement

Presentation Framework

UIElement

Control

Application DependancyObject

Visual Freezable

We refer to the classes in Figure 11-5 as core classes because they provide support for the major concepts

in the WPF architecture. There are many other classes in the framework, most of which utilize the classes

illustrated in Figure 11-5. Understanding these core classes will provide a solid foundation for working

with the WPF framework in your applications—for instance, knowing which base class to inherit from

when creating custom controls in WPF. In the following sections, we look at each of the classes illustrated

in our diagram to understand what they offer and how they fit into the big WPF picture.

Before you begin exploring these classes, it’s worth noting that the classes themselves are part of two

separate framework layers:

Presentation core: Provides base classes that support low-level functionality, such as threading,

properties, rendering, and visuals.

Presentation framework (and the classes within): Extend classes in the presentation core and

add application-level support for layout and composition.

Dispatcher Object

WPF objects belong to the thread on which they are created and cannot be accessed directly by any other

thread. In the context of WPF applications, this thread is called the UI thread. An object that participates in

this single-threaded model is said to exhibit thread affinity, meaning they are tied to the thread on which

they are created. Thread affinity is an important concept to understand when programming in WPF.

There is a class in WPF, called the Dispatcher, that manages all access to the thread on which it is created.

There is only one Dispatcher object per thread. Objects created in WPF are actually tied directly

to the Dispatcher rather than being tied directly to the UI thread itself; however, the net effect is the

same. WPF objects are tied to the Dispatcher through inheritance because most objects in WPF derive

directly or indirectly from DispatcherObject.

Dispatcher manages an event queue in WPF, which you can think of as the message loop in Win32. If a

thread other than the one on which the Dispatcher was created wants to update an object on the thread

owned by the Dispatcher, it must do so by placing a request in the Dispatcher queue. The

Dispatcher will deliver the message in a thread-safe way to a specific target object. We talk about

threading concepts in greater detail in a later section on WPF threading.

The DispatcherObject class represents an object that is associated with a Dispatcher. Therefore,

objects that derive from DispatcherObject are associated with a single thread, the thread associated

with the dispatcher instance to which their base class, DispatcherObject, is associated. For example, if

you create a Button instance in a WPF application, the button can only be accessed directly on the UI

thread because the button ultimately derives from DispatcherObject, which is associated with a dispatcher,

which is associated with the UI thread. DispatcherObject is the lowest level class in the framework

hierarchy, and because almost all objects inherit from it, most objects are inherently thread-safe.

DependencyObject/DependencyProperty

WPF introduces a new property system, the dependency property system (DPS). While typical Get and

Set CLR properties are still supported in WPF, the DPS provides a new set of property types and property

services to objects that derive from DependencyObject.

The DependencyObject class represents an object that participates in the WPF DPS. When an object

derives from DependencyObject, it automatically has access to all of the services provided by the DPS.

A dependency object may declare dependency properties. The DependencyProperty class represents a

dependency property that is registered with the WPF dependency property system.

DPS concepts were covered in earlier chapters, so we’ll just briefly recap here. The DPS offers many

advantages over plain CLR type properties. For instance, through the use of a new type of properties

called dependency properties, the DPS supports property-value inheritance, which allows elements to

inherit property values from any of their containing elements. Dependency properties also provide the

glue required for data binding and animation. Additionally, the DPS supports another new type of property,

called an attached property, which is a dependency property with a twist. Attached properties are

interesting in that they provide a mechanism by which one class can define a property that can be used

by other classes, without the other classes knowing anything about the property or the class that defines

it. Examples of these can be found in many of the built-in layout controls to provide a means for child

controls to position themselves in their parent containers. One such example is the DockPanel.Dock

attached property.

Additionally, the DPS provides a storage system for dependency property values and will notify objects

when these values change. In doing so, each instance of a class that contains dependency properties does

not have to provide storage for those properties. For instance, if you are defining number of labels on a

form, chances are the background color property will be initialized to the default value and will rarely

change. Without the DPS, if you had ten instances of the label class, all of which simply use the default

background color property, you would be storing ten background color property values. The DPS, on

the other hand, can manage this for you, storing only a single instance of the default value, assigning it

to all instances of your class, and then storing separately only the instance properties that are different,

minimizing the use of system resources.

Dependency properties are used most often when working with the DPS. Dependency properties are registered

with the DPS when they are declared. You declare a dependency property in a class by defining a

static field of type DependencyProperty, initialized with a call to the DependencyProperty.Register()

or DependencyProperty.RegisterAttached() method.

public static DependencyProperty text = DependencyProperty.Register(...)

Once registered, your property is managed by the DPS and will provide all the services supplied by the

DPS.

Application

Application is the primary class in the WPF application model. The Application class encapsulates

your code and provides the interface between that code and the operating system. One could say that

Application provides the glue that binds your XAML pages together into a unified application, and

that would be correct, only it does much more than that.

Application exhibits three primary characteristics: It exists from startup until application shutdown

(lifetime support), it is global, and it is local to the machine it is running on.

The Application class provides lifetime support services for your applications. Lifetime support

refers to the stages an application goes through, such as startup, shutdown, and the events in between.

A number of events, including Startup, Activated, Deactivated, SessionEnding, and Exit, occur

during the lifetime of an application. You can use these events to customize the behavior of your application.

For instance, you can hook into the Startup event to add global properties for use throughout

your application.

The Application class also provides a global Properties property for storing application state in a

simple key/value dictionary collection. You can use this to store and manipulate data between windows;

for instance, if you’re familiar with ASP.NET, the Properties property will remind you of the session or

application objects. The Properties property offers an opportunity to store data you want to share

between all windows in your application, or to track state of various objects throughout the lifetime of

your application.

Freezable

The Freezable class exists in the framework to increase application performance when using objects

that do not require interactive behavior. A Freezable object has two states, frozen and unfrozen. An

unfrozen Freezable object has all of the support offered by DependencyObject. When frozen, a

Freezable object becomes read-only, and because it cannot be modified, it does not need the support of

the dependency object, such as change notification. This is where the performance improvement happens.

This benefits objects such as Brush and Pen. The Freezable class improves performance because

the graphics system does not need to monitor frozen objects for changes.

Visual

The Visual class provides services and properties that are common to all visual objects. Visual provides

core services such as rendering and hit-testing to elements that derive from it. If your control or

element renders pixels, it derives from Visual.

Visual implements the IElement interface, which provides methods and properties, such as AddChild

and RemoveChild, which allow elements to exist in a visual tree. IElement is not publicly exposed, but

knowing a little about it helps you to understand some of what Visual provides. If you were to write

your own implementation of a tree class and container it might look something like this:

public class tree

{

IList trees = new IList();

...

}

public class treeItem

{

bool hasParent;

treeItem parent;

bool hasChildren;

IList children = new IList();

...

}

While you can be absolutely certain the implementation of the IElement interface looks nothing like

this, the code illustrates the concept of IElement and a visual tree. A visual tree is simply a collection of

Visual objects. An application will usually contain many elements, and all elements inherit from

Visual, so elements are by their definition readily equipped to be part of a visual tree, and that is

exactly where they will end up.

The visual tree will eventually be passed to the composition system (remember the message transport?),

which will traverse the elements of the tree, processing each element’s drawing instructions, composing

the UI, and ultimately rending pixels to the screen. Drawing instructions contain vector graphics data

that tell the composition system how to render an element.

Now that you understand the visual tree in greater detail, let’s recap. The visual tree contains a hierarchy

of elements, each of which derives from Visual, which means it knows how to live in the visual

tree, and each of which contains its rendering instructions, which tell the composition system how to

render. The purpose of the visual system is now made clear; it offers support to elements through its

base class Visual, and it manages a visual tree, which provides the elements needed by the composition

system in order to render pixels to the screen.

Visual offers support for other features as well, such as transformations, clipping, and hit-testing.

Notice, however, that Visual does not provide support beyond the single element that derives from it.

Non-rendering features, such as event routing and handling, layout, style, and data binding, are not supported

at this level. They are supported by either UIElement or FrameworkElement, which derive from

Visual. You look at these classes in more detail shortly.

In addition to Visual, there are three additional visual classes in WPF: ContainerVisual,

DrawingVisual, and Viewport3DVisual. We’ll just discuss DrawingVisual briefly, as it is a

lightweight class you can use for custom drawing. The DrawingVisual class provides a

DrawingContext object, which is a drawing surface on which you can draw. DrawingVisual does not

support layout, input, focus, or events. In order to get these services, a DrawingVisual instance must

belong to a container that derives from FrameworkElement.

You now know that an application may contain many visual elements, and that these visual elements,

along with their rendering instructions, compose the visual tree. Given this description, you might

expect to see a visual tree representing a simple window, as illustrated in Figure 11-6.

Figure 11-6

Window

StackPanel

Button

actually represents a logical tree rather than a visual tree. The logical tree is made up of the

controls you place in your UI, such as Window, Button, or StackPanel. Remember, however, that in WPF,

each control is composed of shapes, lines, rectangles, and so on. The following example should enforce

the difference between logical and visual trees. So, if you go ahead and enumerate your element tree as a

visual tree, you see the following:

-Trees.Window1

--System.Windows.Controls.Border

---System.Windows.Documents.AdornerDecorator

----System.Windows.Controls.ContentPresenter

-----System.Windows.Controls.StackPanel

------System.Windows.Controls.Button

-------Microsoft.Windows.Themes.ButtonChrome

--------System.Windows.Controls.ContentPresenter

---------System.Windows.Controls.TextBlock

----System.Windows.Documents.AdornerLayer

So what’s going on here? Why does the visual tree contain so many elements? Figure 11-7 illustrates elements

that make up the Button control.

Figure 11-7

We declared a button, but we didn’t declare any of the button’s child elements that appear in the visual

tree. Button is composed of various other elements that make up its visual appearance. This is achieved

through the use of a control template. A control, such as our Button, is composed of one or more elements:

shape, border, brush, and so on. In the case of the button illustrated in Figure 11-7,

ButtonChrome, ContentPresenter, and TextBlock child elements are displayed. The visual tree contains

all visual elements and instructions for rendering controls and, therefore, must contain the individual

elements and instructions that make up the control. This is how the logical tree differs from the

visual tree. When the button is rendered by WPF, WPF will render a collection of visual objects, such as

shapes, borders, lines, ellipses, and so on. So visually, your button contains a collection of shapes to be

rendered, but logically your UI simply contains a button.

Remember that a key concept in WPF, when it comes to controls, is the separation of presentation from logic.

Controls are “lookless” in WPF. Controls provide functionality and, optionally, a default visual style.

Button

ButtonChrome

ContentPresenter

TextBlock

In order to further illustrate the difference between the logical and visual tree, let’s build a simple program.

This program will enumerate and display the logical and visual tree of a specified element.

Open Visual Studio and create a new .NET Framework 3.0 application using the Windows Application

(WPF) template and name the application WPFTrees. Modify the Window1.xaml file as follows:

xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”

Title=”WPFTrees” Height=”304” Width=”702” Name=”MyWindow”

>

Logical Tree

Width=”500” Height=”115”

TextWrapping=”Wrap”>

Visual Tree

Width=”500” Height=”115”

TextWrapping=”Wrap”>

Width=”100” Fill=”Red”>

HorizontalAlignment=”Left” Margin=”1,4,4,4”

Click=”buttonPrint_Click”>Print Trees

In the Window1.xaml file, you’ve defined a DockPanel as your element container. Within it, you’ve

placed a StackPanel containing a couple of Label and TextBox elements for displaying your output,

and a StackPanel that will contain a Canvas. The Button contained by Canvas is what you’ll use as a

root element for displaying your logical and visual trees.

Next, open up the Window1.xaml.cs code-behind file and modify as follows:

using System;

using System.Collections.Generic;

using System.Text;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Shapes;

using System.Collections;

namespace WPFTrees

{

public partial class Window1 : System.Windows.Window

{

public Window1()

{

InitializeComponent();

// CANNOT PRINT TREES IN WINDOW1 CONSTRUCTOR

// THE TREES AREN’T CREATED YET !!!!!

}

public void PrintVisualTree(int indent, ref string str, Visual visual)

{

string space = “”;

for (int count = 0; count <>

{

space += “ “;

}

str += space + visual.GetType().ToString() + Environment.NewLine;

for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)

{

indent++;

PrintVisualTree(indent, ref str,

(Visual)VisualTreeHelper.GetChild(visual, i));

}

}

First, create your method for printing your visual tree. This method will be called when the program’s

print button is clicked. This function accepts an object of type Visual because all elements ultimately

derive from Visual, an indent level for display, and a reference parameter used to create your output

text because this method uses recursion. This function uses the VisualTreeHelper class, which is a

static WPF class available for working with the Visual tree.

We stated that all elements ultimately derive from Visual, and this is true for typical applications. 3D

elements, however, derive from Visual3D. Visual tree nodes derive from either the Visual or

Visual3D WPF classes. You’re not using 3D here, so you can get away with using a parameter of type

Visual.

Now you need to create a method to print your logical tree.

public void PrintLogicalTree(int indent, ref string str, Object obj)

{

if (obj is FrameworkElement)

{

FrameworkElement element = (FrameworkElement)obj;

string space = “”;

for (int count = 0; count <>

{

space += “ “;

}

str += space + element.GetType().ToString() + Environment.NewLine;

IEnumerable children = LogicalTreeHelper.GetChildren(element);

foreach (Object child in children)

{

indent++;

PrintLogicalTree(indent, ref str, child);

}

}

}

The PrintLogicalTree method is very similar to the PrintVisualTree method. What’s different here

is that you are using the LogicalTreeHelper class. This is a static class that provides methods for

working with the logical tree. Note that the LogicalTreeClass also provides a GetChildren method,

as opposed to the VisualTreeHelper class, which provides a GetChildrenCount method. This is why

you can use IEnumerable to enumerate the collection.

Finally, you need to add your print button handler:

private void buttonPrint_Click(Object sender, RoutedEventArgs e)

{

string lt = “”;

PrintLogicalTree(0, ref lt, this.button1);

this.textbox2.Text = lt;

string vt = “”;

PrintVisualTree(0, ref vt, this.button1);

this.textbox1.Text = vt;

}

}

}

Here you simply call the methods you’ve defined, and pass the output to the appropriate TextBox element

on your form. You are passing button1 to your methods as the element to enumerate. You can

change this to be any element you like.

Press F5 to run the application. Figure 11-8 illustrates the results.

When you press the Print Trees button, our application enumerates the logical and visual trees and displays

them. What is being enumerated is the Button, which contains an Ellipse as its content. As you can

see, the logical tree displays only the Button and the Ellipse, but the visual tree shows two additional

items, the ButtonChrome and ContentPresenter. These are graphical objects the visual system needs to

know about in order to render the Button control.

UIElement

The UIElement class derives from Visual and marks the beginning of functionality that supports user

interaction in WPF elements. In terms of elements, Visual represents a simple, non-interactive graphic.

UIElement extends Visual by adding interactivity, such as, layout, input, focus, and events to an element.

UIElement provides the definition for major interactive subsystems in WPF.

The layout system, covered earlier in this book, manages the size and position of an element through a

two-step process of Measure (requesting desired size from child elements) and Arrange (telling an element

what size it can be and where it should be located). UIElement provides two primary methods

used in the WPF layout system, Measure and Arrange, and as such is the base class for elements that

participate in the WPF layout system such as Panel. The final implementation of layout is defined by

classes that derive from UIElement, such as FrameworkElement.

UIElement implements the IInputElement interface. The IInputElement interface defines the common

events, properties, and methods for basic input processing in WPF. UIElement’s implementation of

the IInputElement interface is how UIElement provides support for input, events, and the WPF event

routing subsystem. In a nutshell, UIElement knows how to respond to keyboard and mouse input and

how to raise events.

UIElement also adds an OnRender method, which provides a DrawingContext for drawing text and

graphics. When you want to perform custom drawing, UIElement provides OnRender, which you can

use to draw to a specific rectangular region on the screen.

UIElement is an extremely functional class. We’ve only scraped the surface here and discussed some of

the primary functionality provided. Understanding this class is important when developing WPF applications.

For instance, in order to know why an element is positioned a certain way requires that you

understand the layout system and UIElement’s place in that system.

FrameworkElement

All the classes defined until now are part of the presentation core. Presentation framework is built on top

of presentation core and defines a class called FrameworkElement, which derives from UIElement. The

WPF presentation framework really just wraps and extends the presentation core. Any framework can

implement a “FrameworkElement” class that derives from UIElement and get all of the functionality it

provides. The WPF presentation framework is one such element implementation.

All elements in WPF derive, directly or indirectly, from FrameworkElement, which in turn derives from

UIElement. FrameworkElement extends UIElement by adding the following characteristics: extended

layout, styles, and data binding.

FrameworkElement extends the layout functionality provided by UIElement. Methods defined as in

UIElement such as Measure, MeasureBase, Arrange, and ArrangeBase, are extended and implemented

in FrameworkElement in order to specify WPF framework–specific features.

FrameworkElement adds layout properties, such as Min/Max Width, Min/Max Height, Width, Height,

AcutalWidth, ActualHeight, Margin, HorizontalAlignment, and VerticalAlignment to further control element

layout.

FrameworkElement provides support for data binding. FrameworkElement offers the DataContext

property, which provides a way in which you can define a data source for binding purposes. When the

DataContext property is set on an element, all children of the element also inherit the data context. This

provides for greater flexibility at design time.

FrameworkElement also provides a Resources property, which returns the associated resource dictionary.

Resources are typically defined at the Window or Page level, but can also be defined at the element

level, making the resource dictionary easy to find and access or bind to from an individual element.

Control

FrameworkElement provides all the functionality needed to build an element that fits neatly into the

WPF programming model, such as layout, input, and event support. FrameworkElement’s base classes

provide support for drawing, thread affinity, and the WPF property system. WPF provides a control

library that consists of the controls you would expect to find in a programming API, such as Button,

TextBox, ListBox, and many more. Control provides the base class for all these controls.

Control derives from and extends FrameworkElement by adding support for additional features, such

as context menus, tooltips, and control templates, and by providing additional properties such as

Background and Foreground. Using the Control base class, you can define custom controls, should

you need them.

Controls in WPF are referred to as lookless, meaning they provide behavior separate from appearance.

The Control base class allows you to define behavior specific to a particular control. Button, for example,

provides behavior through its Click event: A button is a clickable control.

A control’s default appearance is defined in a Control Template and a developer should be free to supply

his own template, should he want to change the default look-and-feel. For example, a Button provides a

default Control Template for its appearance, which is a Rectangle with a Border. You can apply your

own Control Template, which might have an Ellipse and no Border, to change the button control’s

appearance, but its behavior remains unchanged.

The following example illustrates the separation of a control’s behavior from its appearance. Create a

new WPF application, and modify the default window’s XAML as follows:

xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”

Title=”ControlTemplate” Height=”300” Width=”300”

>

Stroke=”Red” StrokeThickness=”2”/>

HorizontalAlignment=”Center”>

Foreground=”White” Click=”button1_Click”>Press Me!

In the preceding XAML, we have simply created a ControlTemplate, set its TargetType to Button,

and defined a new appearance in the form of an Ellipse with a green Fill and red Stroke. We’ve

added a ContentPresenter so that our modified button will be able to participate in the WPF content

model. We have also set our button’s Template property to use our new Control Template. Finally, we

define a Click event for our button, to demonstrate that although we’ve changed the button’s appearance,

the behavior remains unchanged.

Switch to the code-behind and add the following event handler.

private void button1_Click(object sender, RoutedEventArgs e)

{

MessageBox.Show(“Hello WPF!”);

}

Press F5 to run the application. Clicking the button prompts a MessageBox to appear. You have effectively

changed the appearance of the built-in WPF Button control using a Control Template. What’s

important here, is that your behavior did not change, illustrating the separation of a control’s appearance

from its behavior.

Probably the most functional control in the WPF framework is Window itself. Window derives from

ContentControl, which derives from Control. Window represents a top-level control container and

serves as the primary interface between a user and an application. We don’t need to dive into the details

of Window because we should all be intimately familiar with it. What’s interesting to note is that in WPF

it is, in essence, simply a control.

A Deeper Look at XAML

XAML is an XML-based language used to declare WPF objects, properties, and event handlers using

XML elements and attributes. Objects and properties defined in XAML map directly to WPF objects and

properties. You have seen many examples thus far of using XAML in your WPF applications. It is important

to note that XAML is its own language and, as such, can be run independently of the WPF runtime.

Standalone XAML is referred to as loose XAML. The PresentationHost.exe is responsible for hosting standalone

XAML and essentially creates a Page object as the root container for XAML elements. You cannot

use Window as a root object for standalone XAML. You can create a standalone XAML file and run it

right in Internet Explorer. We mention “loose” XAML just to enforce the point that XAML is its own

entity. What we are interested in here is how WPF utilizes XAML. When XAML is used with WPF, it

allows you to define your UI in a declarative manner, separate from your procedural code.

In this section, you take a deeper look at XAML and how XAML integrates with WPF applications. You

will look at the following:

XAML under the hood

Manipulating XAML on-the-fly

Deconstruction Window1.xaml

XAML markup extensions

XAML and custom types

XAML Under the Hood

Raw XAML files are simply XML files that define an element hierarchy. In the WPF model, what you’re

typically doing is defining your UI objects and setting object properties, and you’re doing this declaratively

rather than programmatically. In Windows Forms, your objects and event handlers were defined

in your Forms InitializeComponent method. The following shows a button declaration in a Windows

Forms application:

private System.Windows.Forms.Button button1;

this.button1 = new System.Windows.Forms.Button();

this.button1.Location = new System.Drawing.Point(15, 35);

this.button1.Name = “button1”;

this.button1.Size = new System.Drawing.Size(75, 23);

this.button1.TabIndex = 1;

this.button1.Text = “Press Me!”;

this.button1.UseVisualStyleBackColor = true;

this.button1.Click += new System.EventHandler(this.button1_Click);

Because the button is defined in the Windows Forms class (partial class, actually), you have access

to the button in your code-behind. A button field is created, properties populated, and events wired to

handlers.

Here is the markup for the same button defined in XAML:

Press Me!

This declares the same button object, property values, and event handler in XAML, but your codebehind

doesn’t know it exists yet. How is it then that when you compile a WPF application, you are able

to access and utilize the elements from your code-behind? To understand the answer to this question,

you need to look at what happens to your XAML files when you compile your WPF application.

Typically, in your WPF applications, you will want to compile your XAML with your application code.

When you compile, you are able to manipulate the XAML elements much easier than if you load your

XAML dynamically.

WPF uses a markup compiler to process XAML code. When you compile your XAML files, the markup

compiler performs a number of steps for you, including parsing and code generation, the output of

which are some new files placed in your application’s Obj\Release folder. The markup compiler performs

the following steps:

The markup compiler parses your XAML file.

The markup compiler creates a binary representation of our object hierarchy (called BAML) and

saves it with the file extension .baml.

The markup compiler generates a language-specific code file and saves it with a file extension of

.g.cs or .g.vb, depending on the language specified (g stands for “generated”).

Figure 11-9 illustrates the relationship of XAML to the .NET objects and how you can move between the

two dynamically or through compilation.

The BAML file created by the markup compiler is a binary representation of your XAML file. The BAML

file is stored as an application resource in your assembly. The obvious reason for converting a text-based

XAML file to binary is performance. BAML has already been parsed and is readily consumable by your

application.

The partial class created by the markup compiler is a CodeDom representation of the XAML file. This

file provides definitions similar to those created for you in Windows Forms applications, such as fields

and names representing your objects. This file is responsible for loading your BAML resource for your

application, resulting in a visual tree readily available to you in your code-behind. This file also hooks

up event handlers.

You do not have to compile XAML during the build process, but there are compelling

reasons to do so. Alternatively, you can load your XAML files through code

(more on this later), but you will incur a performance hit for this. Loading XAML at

runtime involves parsing the XAML file, mapping CLR types, and validating properties,

all of which affect performance at runtime.

Let’s look at an example:

1. Create a new WPF application and name it HelloXAML.

2. In the Window1 page, add the following XAML markup. You are declaring a window as a toplevel

container and adding to it a StackPanel, TextBlock, and Button. You are also declaring

a name and an event for your button. This will enable you to see how XAML connects your UI

elements to your C#.

xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”

xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”

Title=”Hello XAML” Height=”100” Width=”200”

>

Welcome Message

Click Me!

3. Now open the Window1.xaml.cs class and add an event handler for your button.

public partial class Window1 : System.Windows.Window

{

public Window1()

{

InitializeComponent();

}

private void button1_Click(object sender, RoutedEventArgs e)

WPF

Application

Compiled to BAML Application.LoadComponent()

XamlReader.Load

Compile-time

.NET Objects

Runtime

XAML

XamlReader.Save

{

MessageBox.Show(“Hello XAML!”);

}

}

4. Run the application, and you see your simple form.

5. Click the button, and the button event handler fires, and you will see the message “Hello

XAML!”

Although this is probably one of the simplest applications you can build, it provides a good example for

looking at how XAML is compiled with your application. One thing to point out here is that inside the

Window1 constructor is a call to the InitializeComponent method, which is located in the

Window1.g.cs file that was generated for you at compile time. Let’s take a look at what this method does

for you. (For readability, we’ve removed the attributes applied by the compiler.)

public partial class Window1 : System.Windows.Window,

System.Windows.Markup.IComponentConnector

{

internal System.Windows.Controls.StackPanel stackpanel1;

internal System.Windows.Controls.Button button1;

private bool _contentLoaded;

public void InitializeComponent()

{

if (_contentLoaded)

{

return;

}

_contentLoaded = true;

System.Uri resourceLocater = new

System.Uri(“/HelloXAML;component/window1.xaml”, System.UriKind.Relative);

System.Windows.Application.LoadComponent(this, resourceLocater);

}

void Connect(int connectionId, object target)

{

switch (connectionId)

{

case 1:

this.stackpanel1 = ((System.Windows.Controls.StackPanel)(target));

return;

case 2:

this.button1 = ((System.Windows.Controls.Button)(target));

#line 9 “..\..\Window1.xaml”

this.button1.Click += new System.Windows.RoutedEventHandler(this.button1_Click);

#line default

#line hidden

return;

}

this._contentLoaded = true;

}

}

public partial class Window1 : System.Windows.Window,

System.Windows.Markup.IComponentConnector

The Window1.g.cs file is located in your application’s Obj\Release or Obj\Debug folder depending on

your compiler settings. The first thing to notice is that the partial class generated for you implements the

IComponentConnector interface. This interface provides two methods: InitializeComponent and

Connect. These methods essentially load and connect your XAML element tree to your code.

internal System.Windows.Controls.StackPanel stackpanel1;

internal System.Windows.Controls.Button button1;

Next, you see that fields have been defined for your XAML elements. Fields are only defined for elements

that declare a Name attribute. The name you specify in your element is the name you use to reference

the .NET object created for you in your code-behind. In the XAML declaration file, you declared

names for the StackPanel and Button but not for TextBlock, and this is reflected here. You will not

have access to the TextBlock element in your C# code because you did not define a name. These fields

are what you will now use in your C# code to reference your controls.

public void InitializeComponent()

{

if (_contentLoaded)

{

return;

}

_contentLoaded = true;

System.Uri resourceLocater = new

System.Uri(“/HelloXAML;component/window1.xaml”, System.UriKind.Relative);

System.Windows.Application.LoadComponent(this, resourceLocater);

}

The InitializeComponent method that is called from the constructor in your Window class is defined

here. Inside the InitializeComponent method, you see a call to the LoadComponent method of the

Application object. Essentially, this method loads your XAML, which is now BAML stored as a

resource embedded in your application, into our application object. Once loaded, LoadComponent converts

it to an element tree and sets the target object to the root element, in this case Window1. Now you

have access to your element tree from C#.

void Connect(int connectionId, object target)

{

switch (connectionId)

{

case 1:

this.stackpanel1 = ((System.Windows.Controls.StackPanel)(target));

return;

case 2:

this.button1 = ((System.Windows.Controls.Button)(target));

#line 9 “..\..\Window1.xaml”

this.button1.Click += new System.Windows.RoutedEventHandler(this.button1_Click);

#line default

#line hidden

return;

}

this._contentLoaded = true;

}

The Connect method attaches events and element names to compiled content. In your XAML declaration

file, you declared a Click event on your button. This event gets wired up here.

That is all there is to it. You can now code your application and utilize the elements defined in your

XAML file through your C# code. The magic really happens in the Window1.g.cs file that the compiler

generates for you.