Introduction

This article is the first in a series which reviews some important features of Microsoft's Windows Presentation Foundation (WPF). The entire series barely scratches the surface of the immense WPF platform, and it does not dive too deeply into any particular topic. The purpose of this series is to familiarize the reader with the basic WPF programming model to the point where he/she is comfortable enough with WPF to fully understand the, rather silly, WPF Horse Race application (available for download via a link at the top of this page).

The subject matter is presented in the context of a completely impractical horse racing application, as seen in the screenshot above. The application was designed with the intention of being used as the focal point of this series. I tried to find the right balance between making the demo application simple enough to be understandable to a WPF newcomer, yet complicated enough to actually do something interesting (or at least mildly amusing).

Prerequisites

In order to run a WPF application you need the .NET Framework version 3.0, or greater. Windows Vista has the .NET Framework v3.0 installed by default, so you only need to install it if you have Windows XP SP2.

To develop WPF applications you should have Visual Studio 2005 with the "Orcas" extensions, or a later version of Visual Studio, and also the Windows SDK. Refer to the External Links section at the end of this article for links to relevant resources.

What is XAML?

XAML stands for eXtensible Application Markup Language. It is an all-purpose XML-based language used for declaring object graphs, which are instantiated at runtime. XAML is used by WPF developers to declare the layout of a user interface (UI), and the resources used in that UI.

It is not at all necessary to use XAML when programming in WPF. Anything that can be done in XAML can also be done in code. Using XAML makes many UI development scenarios much easier and faster, such as creating the layout of a UI and configuring styles, templates, and other WPF-specific entities discussed later in this series.

Performance impact

When you compile a WPF application in Visual Studio it will compile your XAML files into a compressed representation known as Binary Application Markup Language (BAML). The BAML is then saved as a resource in the resultant assembly. When that assembly is loaded and the resource is requested, the BAML is streamed out and very quickly turned into the object graph described by the original XAML.

This two-step process allows the XAML parsing to occur at compile time, thus mitigating the performance overhead of using a text-based object instantiation technology. With that said, it is possible to load XAML programmatically via the XamlReader.Load method. Dynamically loading XAML can be useful in a variety of situations, such as when a volatile portion of your UI is periodically downloaded from a server via XML Web services.

Basic syntax

Since XAML is an XML-based language, it should be quite simple and straightforward for anyone with XML experience. There are two different uses for XML elements in XAML; elements that represent objects and elements that represent properties of objects. An XML attribute always represents a property or event of an object. That's it; it is that simple. There are a few other concepts built on top of those fundamentals, but XAML never becomes complicated.

That XAML results in a funky little button, which is rendered like this:

Let's dissect that XAML to see how it works. The <Button> element declares that an instance of the Button class will be created. That Button object will have its Content property set to the string "Click Me". The Button's Click event will be handled by a method called OnButtonClick in the code-behind file (we'll get into code-behind files soon).

The next element is <Button.Background>, which is said to use the "property element syntax". That XML element represents the Background property of the Button being configured. The child element of a property element is the value to which the property is set. In this case, the Background property is set to a LinearGradientBrush object.

That brush has two <GradientStop> child elements, which might seem confusing at first. What are those GradientStop objects doing there? What are they being assigned or added to? The answer lies in the fact that XAML has some "shortcuts" built in which allow you to specify a property on a class which is considered to be the "content property." You do not need to use the property element syntax to assign a value to the "content property" of a class. Since LinearGradientBrush's content property is the GradientStops property, the following XAML is equivalent to that seen above:

Markup extensions

The XAML parser also knows how to work with a special construct known as the "markup extension." Markup extensions allow you to compactly configure objects and reference other objects defined elsewhere in the application. They are used when setting a property on an object, either via an XML attribute or the property element syntax. Markup extensions are used for things such as specifying a null value, declaring an array, referencing an object held in a resource dictionary, binding one property to another, and much more.

The following XAML is roughly equivalent to the example shown previously (with a few minor changes):

Notice that the Button's Background property is set, via an XML attribute, to {StaticResource FunkyBrush}. When an attribute is set to a value which begins with { and ends with }, then a markup extension is being used.

In this case the StaticResourceExtension class is being used to reference a LinearGradientBrush stored in the Grid's resource dictionary. (Note: Grid is a layout panel in WPF, not a tabular data presentation control like you might expect.)

Code-behind files

XAML is compiled down into a class. Unless you specify the class name it should use, the compiler will generate a class name for you. However, when you apply the x:Class attribute to the root XML element in a XAML file, you can create a partial class in C# or VB.NET which will be merged with the XAML partial. This is how you can associate behavior with the layout and visuals declared in XAML.

For example, in the demonstration above we created a Button in XAML and assigned an event handling method to its Click event. The OnButtonClick method would be defined in the code-behind file which contains another part of the class associated with the partial class generated by the XAML.

Let's suppose that the Button we've been discussing is in a Window subclass called MyWindow. Here would be the code-behind file (MyWindow.xaml.cs):

How the WPF Horse Race uses XAML

The WPF Horse Race application is almost entirely written in XAML. The application uses three C# files: the code-behind for the main Window, a file for the RaceHorse class, and another which contains some value converters (more on those in the article about data binding). The rest of the application is all in XAML.

I encourage you to explore the WPF Horse Race source files and check out what XAML looks like when it's being used to create a real program (as opposed to just a simple demonstration of it). The rest of the articles in this series will examine how that entire application works, but there is no substitute for just digging into the source files now and exploring how it works on your own.

External links

Prerequisites

XAML

General WPF Tips

History

April 1, 2007 - Created the article.

April 3, 2007 - Removed superfluous ColumnDefinitions from the Grid in RaceHorseDataTemplate.xaml and updated the demo project download file.

April 18, 2007 - Fixed an incorrect statement about markup extensions. Originally I asserted that they are only used in conjunction with XML attributes, but they can be used with the property element syntax, as well.