Windows
Presentation Foundation (hereafter referred to as WPF
) is a new API for creating graphical user interfaces for the Windows platform. It is an alternative to WinForms that further empowers developers by providing an API capable of taking full advantage of the multimedia facilities of the modern PC. Unlike WinForms, it does not wrap Win32 but is completely new, built from the ground up using .NET. The fundamental power of WPF
comes from the fact that it is vector based, hardware accelerated and resolution independent.
Reminiscent of WinForms, you'll find many of the controls you are used to when building applications: Button
, ComboBox
, ListBox
, etc. However, in WPF
, your UI design is represented in a completely different fashion. Instead of using a designer generated code file or a resource file as the source of a UI definition, WPF
uses XML
. Specifically, it uses XAML
. Please, don't let this frighten or dissuade you. It's surprisingly intuitive and much easier than you would think (not to mention fun). There are many other new features in WPF
, too many to discuss in this tutorial. Below, you can see a chart depicting what I consider to be some of the most important features/innovations in WPF
.
Figure 1: Important WPF Features
The right column of the chart lists some technologies that you may be familiar with that parallel the ideas in WPF
. Hopefully this gives you a starting point for understanding the terms on the left. Don't take the parallels too literally; there are differences. We'll talk about each of these areas over the course of this article and I will provide additional resources for going into greater depth as well.
Besides the above mentioned features, there is a new type of application. The standard WindowsXAML
Browser Application (.xbap). When you deploy this type of application to a web server, users can navigate to a URL and run your program from within the IE sandbox. The experience is similar to using a Flash
application, but is restricted to users of IE (versions 6 and 7 and any browser that supports the WebControl
, such as Firefox through its IE tab). You can begin to imagine the types of rich intranet applications you could build for a company if you were given IE and WPF
as the platform. At the same time, it's too bad that it only works in IE. To address this issue, Microsoft is currently working on Silverlight
(formerly WPF/E
), a cross-platform, cross-browser subset of the .NET Framework and WPF
. application is alive and kicking, but you now have an additional option: the
If you want to work with WPF
(part of .NET 3.0) there are a few things you are going to need. First off, .NET 3.0 was designed to work on Vista, XP (SP2) and Windows Server 2003 (SP1). Any one of these OS's and the .NET 3.0 runtime will allow you to run applications built with WPF
. You can get the current version of the runtime here. Installing the runtime will add .NET 2.0 if you don't have it and if you do, it will just add the new assemblies (marked with a 3.0 version designation). I'm guessing that most of you will want to do some development; for that you will need a few more things. The necessities are a version of Visual Studio 2005 and the Windows SDK. (Watch out! The download size is rather large.) If you want to have a more pleasant development experience, you should install the Visual Studio S2005 extensions. Once you get up and running with these pieces I recommend you explore the official site a little bit.
Before I dig into more technical issues I would like to mention a few general items available for learning and working with WPF
. If you have installed the VS extensions for .NET 3.0, then you now have the Orcas designer available to you. This is a tool much like the WinForms designer, but it is obviously for creating WPF
UIs. It has a tabbed design, so that you can switch back and forth between the visual designer and XAML
markup. The powerhouse design tool is Blend
(formerly Expression Interactive Designer), which you can get here. If you are more graphically inclined, you are going to want to check this out. It is similar to using a tool like Adobe Illustrator, but it generates XAML
and integrates with the VS solution and MSBuild. This is a landmark tool because it makes designers fully fledged members of the development team. No longer do they need to do a UI mockup and deliver it to a developer to implement (or turn down because of its complexity). They can simply build the UI using a set of tools that they are familiar with. A similar third party tool is Mobiform's Aurora. I highly recommend investigating it. There are also numerous plug-ins for exporting 2D/3D art to XAML
from most popular programs. Regardless of whether you are approaching WPF
from a developer or designer's perspective, you are probably going to want a good book on the technology. Currently, the two best resources I know of are Charles Petzold's book Applications = Code + Markup and Adam Nathan's book Windows Presentation Foundation Unleashed.
XAML
XAML
stands for eXtensible Application Markup Language
. You can think of it as HTML
for Windows applications, but it is really quite a bit more expressive and powerful. For those of you code junkies out there, XAML
is really no more than a special type of CLR
object serialization. It was intentionally architected to serialize CLR
object graphs into an XML
representation that is both verbose and human readable. The reasoning behind this was to make it possible for developers to easily edit the markup by hand and enable the creation of powerful graphical tools that could generate markup for you behind the scenes. When you compile an application that contains XAML
files, the markup gets converted into BAML
. BAML
is a tokenized, binary representation of XAML
. This binary representation is then stored inside the application's resources and loaded as needed by WPF
during the execution of your program. The main advantage of this approach is that you get a faster UI load time by reading a binary stream than through parsing XML
.
The best way to get to know XAML
is by looking at some examples. So without further ado, let's begin by comparing two markup fragments:
HTML Fragment
1.
<
div
style
=
"border: solid 5px black; margin: 10px; padding: 5px"
>
2.
<
input
type
=
"button"
value
=
"Click Me!"
/>
3.
</
div
>
XAML Fragment
1.
<
Border
BorderBrush
=
"Black"
BorderThickness
=
"5"
Margin
=
"10"
Padding
=
"5"
>
2.
<
Button
>Click Me!</
Button
>
3.
</
Border
>
Figure 2: A Button with Border
Both of these fragments accomplish the same effect on their respective platforms: creating a button
XAML
any more than HTML
; this is for demonstration purposes only.). I started with this example so that we could compare XAML
to something more familiar, HTML
. I think that if you are honest, however, you will agree that the XAML
HTML
fragment. It is intuitive. One of the reasons for this is that, generally speaking, the element tags map directly to Types
and the attributes map to Properties
with a border around it (Note: Declaring styles inline is not a best practice in fragment is much more expressive than the on those Types. Since WPF's class hierarchy was very carefully designed, you'll find that many elements have the same available attributes. This consistency makes for smooth, natural learning.
Using XAML
, you can represent a wide variety of UI related constructs. These include things like controls
, layout panels
, graphics primitives
, 3D content and even animations
. Let's look at another example. This time we will draw a graphics primitive:
1.
<
Ellipse
Width
=
"200"
Height
=
"150"
>
2.
<
Ellipse.Fill
>
3.
<
LinearGradientBrush
>
4.
<
GradientStop
Offset
=
"0"
Color
=
"Teal"
/>
5.
<
GradientStop
Offset
=
"1"
Color
=
"Aqua"
/>
6.
</
LinearGradientBrush
>
7.
</
Ellipse.Fill
>
8.
</
Ellipse
>
Figure 3: An Ellipse
The first line of this example is pretty simple. We have an Ellipse
whose Height
and Width
Ellipse
, on the other hand, is something different than what we have previously seen. In this case we wanted to represent a linear gradient brush for filling the Ellipse
. But how could we represent all of that information using the standard attribute syntax? It turns out that this is a very common scenario, and to solve the problem we have something called Property Element Syntax. In XAML
, you can turn any attribute (property on the class) into a child element by using this pattern: ElementName.AttributeName
(TypeName.PropertyName
). So in this case we are assigning the enclosed linear gradient brush to the Fill
property of the Ellipse
. If you're very keen, you'll notice that there is a discrepancy between what I just told you and what is happening with the child nodes of LinearGradientBrush
. I have defined a set of gradient stops for the brush, but what property are they being assigned to on the brush? In fact they are being assigned to the GradientStops
property, but where is the element name LinearGradientBrush.GradientStops
? How does the XAML
parser know to assign to this property? Again, we have a common scenario. Any object can declare a default content property to which its child nodes will be assigned automatically. In this case GradientStops
is the default content property. You have actually seen this in action in the very first example: properties are being set. The child element of
1.
<
Button
>Click Me!</
Button
>
On the button there is a property called Content
that is set as the default content property for the button
. This is how the XAML
parser knows what to do with the text Click Me! Let's do one final example. This time we'll do something different with the button's content, since it is a bit of a special property:
01.
<
Button
>
02.
<
Ellipse
Width
=
"200"
Height
=
"150"
>
03.
<
Ellipse.Fill
>
04.
<
LinearGradientBrush
>
05.
<
GradientStop
Offset
=
"0"
Color
=
"Teal"
/>
06.
<
GradientStop
Offset
=
"1"
Color
=
"Aqua"
/>
07.
</
LinearGradientBrush
>
08.
</
Ellipse.Fill
>
09.
</
Ellipse
>
10.
</
Button
>
Figure 4: A Button with Ellipse content
It happens that the Button
(and many other controls) inherits from a class called ContentControl
. This is where it gets its Content property, mentioned earlier. The type of Content
is object
, which allows you to fill it with any CLR
type. For most objects, WPF
will simply call ToString()
and render the value. However, you can also set the content to any renderable WPF
object. This means that the button's content could just as easily have b