One of the hottest topics among developers is Windows Presentation Foundation (WPF), a new graphics subsystem that promises to simplify the task of the developer while bringing significantly enhanced visual experiences to the end user. Formerly code-named Avalon, WPF is one part of what is now called WinFX, the set of "next generation" (Microsoft's words, not mine) managed APIs for application development.
This is the first in a series of two articles on WPF.
Today, we look at the goals of WPF and learn about Extensible Application Markup Language, or XAML, the declarative markup vocabulary that is part of WPF. The second article will delve into WPF programming with Visual Studio.
Before getting into the details of WPF let's take a quick look at WinFX.
In addition to WPF, the components of WinFX are Windows Communication Foundation (WCF) for building service-oriented apps, Windows Workflow Foundation (WWF) for capturing business process flow and translating it into code, and InfoCard for providing security identities.
It's important to understand that WinFX and its components are not a replacement for the .Net framework or for the Common Language Runtime. Rather, you should think of WinFX as a meta-framework that sits on top of the .Net framework, as shown in Figure 1. In technical terms, WinFX is nothing more than another set of namespaces and classes for use in developing .Net applications.
WinFX will be released with Windows Vista at some time in the not-too-distant future, probably early 2007. This will also probably coincide with the release of .Net 3.0.
WinFX is not Vista-specific, however, and it is designed to be used with either version 2 or version 3 of .Net and also to create apps for Windows XP as well as Vista.
WPF was designed with three primary goals in mind. The first was a composable user interface, meaning the ability to be either code-based, like Windows forms or Microsoft Foundation Classes, or markup-based, like HTML pages. Markup-based UI development offers several advantages, such as separating UI design from coding. Microsoft will provide for WPF a design tool named Sparkle — Microsoft Expression Designer — that allows graphic designers to create the UI independent of the project code. It will be possible to integrate the output of Sparkle back into the development
process at any time. It is also planned to include in Visual Studio 2007 a
dedicated WPF design tool.
The second goal was to provide a higher level of user interface experience for the end user. By taking advantage of the fast graphics chips present on most computersystems, WPF will permit designers to create fast and sophisticated UIs that incorporate animation and 3-D effects.
The final goal was easy control and document layout and rendering. WinFX combines the ability to use sophisticated UI controls, such as grids and tables, with the easy of rendering and text flow that is characteristic of web pages.
An important aspect of WPF is that it uses a vector-based rendering engine, which is fundamentally different from the raster-based engines used previously. A raster-based engine defines display elements in terms of pixels. As screen and printer resolution increase, it has become problematic to render so many pixels in an efficient manner while maintaining high quality output across all resolutions. In contrast, vector-based rendering defines display
elements using a scalable coordinate system so that they are independent of the output device resolution. Of course, some items, such as photographs, will remain raster-based, but the use of vector rendering for fonts and other standard
display elements provides significant advantages.
Getting the Beta Tools
If you are running Windows XP or Windows Server 2003 with all the latest service packs, you can try WPF now. This requires several downloads, and Microsoft is quick to warn that this is beta code with all that implies about the potential for problems. I recommend trying this only on a dedicated system that is not used for any critical tasks. You should definitely read the information that is provided on the download pages.
First, download and install the
WinFX Runtime Components. These are required to run any WinFX application. Next, download and install the
SDK which contains samples, tools, and documentation related to WinFX development. These two downloads are all you need to run WinFX apps and to experiment with XAML.
If you have Visual Studio 2005 and want to use it to create WinFX apps, you also need to download and install the
development tools for VS 2005 which provide project templates, Intellisense support, and documentation for WinFX development in Visual Studio.
After you complete the installation process, you will find a new entry "Microsoft Windows SDK" on your Start menu that provides access to the SDK tools and the ReadMe file. I recommend you actually read this file; it may save you headaches down the road. You'll also have several WinFX project templates in Visual Studio's New Project dialog box.
Introducing XAML
I already mentioned that WPF provides for declarative, or markup based, design of UIs. For this purpose, Microsoft developed Extensible Application Markup Language, or XAML. This is not the only way to develop WPF interfaces, but it is preferred because it lets you separate the UI definition from the program
logic. XAML is itself based on XML and permits the creation of truly
sophisticated UIs that include controls, text, shapes, images, and so on.
Let's look at a simple example that shows how XAML is used to declare a button in the UI:.
<Canvas>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button>Click Here</Button>
</Canvas>
The UI is represented as a <Canvas> element with its associated namespaces. <Canvas> is not the only root element that can be used for XAML files, but it will serve for this example (I'll discuss the various possibilities later). The heart of the definition is a simple <Button> element that encloses the display text. So far so good, but I can hear you asking several important questions:
- How do you define an action to be taken if the button is clicked?
- How do you specify the visual appearance of the button?
- How do you specify the size and location of the element?
As for an action, it is handled in the usual way, by writing an event
procedure that is called when the button is clicked. The procedure is placed in
a code-behind file and linked to the button, as shown here:
<Canvas>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyNamespace.MyCanvasCode">
<Button Click="Button_Click">Click Here</Button>
</Canvas>
You can see that the x:Class attribute of the <Canvas> element identifies the
class that contains the code behind, and the Click attribute of the <Button>
element identifies the specific procedure to be called. If you want code to be
able to modify the control, you must specify the Name attribute to provide
a unique identifier for the control:
<Button Name="Button1" Click="Button_Click">Click Here</Button>
The code would change the control by setting the appropriate property, for example the text on the button:
Button1.Content = "I've been clicked"
A control's appearance is determined by properties, as you might expect. These properties are set as attributes in the XAML tag. This example sets the foreground and background colors of the button:
<Button Background="Green"
Foreground="Red">Click Here</Button>
The final question, that of location and size, is not answered as easily. Sometimes an element, such as a button, is contained within a parent element such as a grid, and its position and size is determined by its
container. Other times, an element's position and size are determined by properties that you set in XAML code. Either way, you have complete flexibility to position elements just where you want them.

Figure 2. XamlPad provides a test bed for XAML code.
The WinFX SDK installation includes a nifty little application called XamlPad, shown in Figure 2. It's a simple little XAML editor that provides a pane for entering XAML and a rendering pane that shows you the result. Errors, if any, are displayed at the bottom of the window. For Visual Studio users, it will seem very basic — no Intellisense, no highlighting of errors, and so on — but
it is very useful for experimenting with XAML and perhaps even testing XAML code to be pasted into a real app at some point.
Looking at the figure, you can see that the rendering includes a textbox, a label, a button, and an image. Here's the XAML code that produced this:
<Canvas >
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Gray">
<Label Canvas.Top="10" Canvas.Left="125"
BorderBrush="Crimson" BorderThickness="4">This is a label
</Label>
<TextBox Canvas.Top="10" Canvas.Left="10" >This is a textbox
</TextBox>
<Button Canvas.Top="10" Canvas.Left="220" Height="25">Guess what this is!
</Button>
<Image Width="320" Canvas.Top="55" Canvas.Left="10" >
<Image.Source>
<BitmapImage UriSource="C:\dsc01836.jpg" />
</Image.Source>
</Image>
</Canvas>
Looks a lot like HTML, doesn't it? That's no accident. By the way, in this code you can see an
example of positioning controls relative to their container — in this case, a Canvas object.
Layout Containers
Every XAML rendering is based on; one or more layout objects that define the overall layout of the elements. In the XAML code, the root element can specify the layout object.
In the example shown above, the Canvas layout object
was used. The Canvas layout lets you position individual elements freely by specifying the Canvas.Top and Canvas.Left attributes. It's very much like
what you are used to in Windows Forms, and provides the greatest amount of flexibility.
The other layout objects are:
- The StackPanel layout object arranges elements in a vertical or horizontal
stack. A vertical stack can be thought of as a table with one column and as
many rows as needed, and a horizontal stack as a table with one row and as
many columns as needed.
- The DockPanel layout object lets you dock elements to the top, bottom,
left, and/or right of the layout area. Additional content can be displayed in
the central area between the docked items.
- The Grid layout object lets you define a grid of cells, much like an HTML
table, with layout elements placed in the various cells.
- The WrapPanel layout object arranges UI elements in the same way that text
is arranged in a word processor: left to right in order, and upon reaching the
right margin starting a new line, continuing left-to-right then top-to-bottom.
As you have seen in previous examples, a layout element can be the root
element in the XAML file when you are testing in XamlPad. In real applications,
the root element will be either <Page>, for web-based applications, or <Window>,
for desktop applications.
The five available layout containers are pretty powerful on their own, but you can greatly increase your layout flexibility in two ways. One is to define your own layout class, based on the Panel class, and override the ArrangeOverride and MeasureOverride methods. These two methods are responsible for positioning a layout object's child UI elements, and you can write the overrides to get just the effect you want.

Figure 3. Using nested layout containers.
The second way to increase layout flexibility is by nesting layout containers. You could, for example, use a Canvas container as the outermost, or parent, container, and then position a Grid somewhere on the Canvas.
Let's look at an example. The layout shown in Figure 3 uses a StackPanel as the parent container, in the
default vertical orientation. The top three items in the StackPanel are a
TextBlock, a Button, and another TextBlock. The next item is a Grid with 4 rows
and 3 columns. The XAML code is shown following the figure.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowTitle="Nesting UI Containers">
<Border Background="LightBlue" BorderBrush="Black" BorderThickness="2"
Padding="5">
<StackPanel Background="White" HorizontalAlignment="Center" VerticalAlignment="Top">
<TextBlock Margin="5,0,5,0" FontSize="24" HorizontalAlignment="Center">
An Example of Nested Layout Objects</TextBlock>
<Button HorizontalAlignment="Stretch" Margin="20">Button 1</Button>
<TextBlock Margin="5,5,5,15" FontSize="14" HorizontalAlignment="Center">
This is text in a TextBlock element</TextBlock>
<Grid VerticalAlignment="Top" HorizontalAlignment="Center" ShowGridLines="True"
Width="350" Height="150">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock FontSize="20" HorizontalAlignment="Center" FontWeight="Bold"
Grid.ColumnSpan="3" Grid.Row="0">This is a Grid layout object</TextBlock>
<TextBlock FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center"
FontWeight="Bold" Grid.Row="1" Grid.Column="0">123456</TextBlock>
<TextBlock FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center"
FontWeight="Bold" Grid.Row="1" Grid.Column="1">123456</TextBlock>
<TextBlock FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center"
FontWeight="Bold" Grid.Row="1" Grid.Column="2">123456</TextBlock>
<TextBlock FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center"
FontWeight="Bold" Grid.Row="2" Grid.Column="0">123456</TextBlock>
<TextBlock FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center"
FontWeight="Bold" Grid.Row="2" Grid.Column="1">123456</TextBlock>
<TextBlock FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center"
FontWeight="Bold" Grid.Row="2" Grid.Column="2">123456</TextBlock>
<TextBlock FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center"
FontWeight="Bold" Grid.Row="3" Grid.Column="0">123456</TextBlock>
<TextBlock FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center"
FontWeight="Bold" Grid.Row="3" Grid.Column="1">123456</TextBlock>
<TextBlock FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center"
FontWeight="Bold" Grid.Row="3" Grid.Column="2">123456</TextBlock>
</Grid>
</StackPanel>
</Border>
</Page>
Two-Dimensional Graphics
WPF provides a set of 2D graphics objects, called shapes, that let you
add graphics to your layouts. There are five shapes, all of which are based on the
Shape class. They are part of the System.Windows.Shapes namespace.
The functions of the Ellipse, Line, Polygon, and Rectangle classes
should be clear from their names. The Path class is used
to draw a series of connected lines and curves, and the Polyline class is used to draw a series of connected
straight lines.
All of these 2D graphics classes have several features in common:
- A
Stroke property that describes how the shape's outline is rendered.
- A
StrokeThickness property that determines the thickness of the outline.
- A
Fill property that describes how the interior of the shape is painted.

Figure 4. An example of using the 2-D graphics objects.
The following code shows a simple example of using the Rectangle and Line objects in XAML. It also illustrates the ability to control the opacity of drawn
elements. Because the line is drawn first, it would normally be hidden behind the rectangle, but by setting the rectangle's Opacity property we can make it partially transparent, permitting the line to show through. Figure 4 shows the output.
<Canvas
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Line
Stroke="green"
StrokeThickness="10"
StrokeStartLineCap="Round"
StrokeEndLineCap="Round"
X1="10"
Y1="50"
X2="350"
Y2="50"/>
<Rectangle
Stroke="Blue"
StrokeThickness="4"
Canvas.Top = "20"
Canvas.Left="30"
Height="160"
Width="300"
Opacity=".6" >
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,.5">
<LinearGradientBrush.GradientStops>
<GradientStop Color="Yellow" Offset="0" />
<GradientStop Color="Red" Offset="0.25" />
<GradientStop Color="Blue" Offset="0.75" />
<GradientStop Color="LimeGreen" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Canvas>
Summary
This article introduced you to XAML, the declarative markup language for
defining WPF user interfaces in WinFX applications. In the next article, we'll
take a look at using WPF in Visual Studio.