In part 1 I discussed why should something like WPF exists. In this part I’ll talk about that thing called XAML. When people first hear there is a new language to learn to use WPF, they instinctively get defensive. Another language? What’s wrong with C#? If it’s good enough for WinForms and a bunch of other technologies, why do we need another language to learn? Isn’t learning WPF bad enough?
The “good” news is that a WPF application can be written entirely in C# and use no XAML at all. Anything that can be done in XAML can be done in code. But that would be missing out.
What is XAML?
XAML (eXtensible Application Markup Language) is an XML based language. That is, XAML is first and foremost regular XML. Its interpretation is what makes it interesting. XAML has very few capabilities, but combining them with its “eXtensible” part makes it pretty powerful. That said, it’s not a replacement for C# or VB or any other “normal” .NET programming language.
XAML is declarative. It says what, rather than how. The declarative approach to programming is pervasive these days, mostly popularized within the .NET world by the Language Integrated Query (LINQ) technology that came out in .NET 3.5 with language support by C# 3.0 and VB 9.0.
XAML started out in WPF, spread to Silverlight and the Workflow Foundation (WF), which hints that it’s pretty agnostic and really unrelated to UI. In fact, it’s possible to create (almost) any type of object in XAML as we’ll see shortly. In .NET 4, XAML took its rightful place as a first class citizen in the System.Xaml.Dll assembly (in the System.Xaml namespace). I’ve written something about that here and here. Note that WPF still uses its own XAML and does not (currently) support the latest XAML implementation (dubbed “XAML 2009”).
XAML Away!
Here’s a very simple XAML we can write:
<Button Content="OK" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />
If we disregard the scary “xmlns” declaration, we have a simple XML element named Button and an XML attribute named Content with a value of “OK”.
The first rule of XAML is, that an element means creating an object instance. In this case it’s creation of an instance of System.Windows.Controls.Button. The second rule of XAML states that an XML attribute means setting a property value. In this case, the property Content of the button is set to “OK”.
To view the results of this XAML, we can create a file (e.g. simple.xaml) with the code above and double click in Windows Explorer. If all is well, Internet Explorer will open the file and render it. You should see a giant button stretched within the client area of IE’s window and the caption “OK” in the center.

Not too impressive for now, but it’s a start.
Creating an instance is possible if the type is non-generic and it has a public default constructor. WPF’s XAML cannot create generic types (possible in XAML 2009) and cannot call any constructor other than the default (again, possible in the new XAML 2009, not part of WPF at the moment). Types that adhere to these constraints are sometimes called “XAML friendly”.
Now what’s this scary looking xmlns declaration? This is an XML namespace declaration, and is technically related to XML. The problem XML namespaces were designed to solve, is what (in this case) should we create? System.Windows.Controls.Button or perhaps System.Windows.Forms.Button or maybe System.Web.UI.Controls.Button or maybe it’s some MyNamespace.Button instead?
This XML namespace tells the XAML parser that the WPF namespaces should be consulted by default for all element names with no prefix. We can add prefixed XML namespaces to be able to create other objects (as we’ll do later).
Let’s try something else:
<Ellipse StrokeThickness="5" Stroke="Red" Fill="Yellow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />
This is similar: Create an instance of the Ellipse class, set its StrokeThickness property to 5, its Stroke property to “Red” and its Fill property to “Yellow”. This is how it looks when opening with IE:

The code above may be a bit strange. What is the type of the Stroke property? Surely it can’t be a string. And it’s not. It’s a Brush. A Brush is an abstract class in WPF from which various brushes inherit. One of those is SolidColorBrush, which is the simplest brush, representing some constant color. How did “Red” got translated to a SolidColorBrush object by the XAML parser? The answer lies with type converters.
A type converter is a class inheriting from System.ComponentModel.TypeConverter that may try to convert a string to another type. In this case, the XAML parser uses the BrushConverter class. Why? Let’s take a look at the declaration of the Brush class:
[TypeConverter(typeof(BrushConverter))]
public abstract class Brush : Animatable, IFormattable, DUCE.IResource {
This is part of the declaration, of course. The key point here is the TypeConverter attribute applied to the Brush type. When the XAML parser sees that types don’t match (and most times they don’t, as XML only understands strings), it checks the target type to see if a type converter exists, and if so, hands it the value from the XML and expects a non-null response. In this case, BrushConverter returns an instance of type SolidColorBrush initialized with a red color. The equivalent code might be something like (assuming the Ellipse’s reference is e1):
e1.Stroke = new SolidColorBrush(Colors.Red);
Technically, this could be further shortened by using the Brushes static class that exposes static properties representing SolidColorBrush objects with 141 predefined color names:
The same goes for the Fill property.
Note that the StrokeThickness property is not a string either – it’s a double. There’s a type converter for that, too (LengthConverter), set on the property itself, as setting it on the double type is not possible (and impractical). The XAML parser checks there, too.
Markup Extensions
Sometimes just setting properties is not enough. Perhaps there is something “declarative” in nature that needs to be applied, but there is no single property or a bunch of properties that can accomplish that. That’s what markup extensions are for. That’s the “eXtensible” part of XAML.
At this time, we’ll look at two existing markup extensions. Generally speaking, markup extensions are classes inheriting from the abstract MarkupExtension and need to override the abstract ProvideValue method.
Let’s look at an example. We want to set the Fill property of the Ellipse to null. In code it’s trivial. In XAML, how would we represent null? Enter the Null markup extension:
<Ellipse xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StrokeThickness="5" Stroke="Red" Fill="{x:Null}" />
Markup extensions start with a curly brace to let the XAML parser know we’re talking about a markup extension. In this case, it’s System.Windows.Markup.NullExtension. Note that we can use the markup extension without the word “Extension” (if exists in the class name).
The XML “x” namespace is mapped here (internally) to the System.Windows.Markup namespace. This is because that’s where the NullExtension class resides. This is not a requirement. Later we’ll encounter other extensions that do reside in the “normal” WPF namespaces. Of course, “x” is just a typical name used for this. You can use any string, just match it when used.
Another simple example of a markup extension is the {x:Static} extension (implemented in System.Windows.Markup.StaticExtension). This markup extension allows accessing any static property. Here’s an example:
<Ellipse xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StrokeThickness="5" Stroke="{x:Static SystemColors.DesktopBrush}" Fill="{x:Null}" />
This makes the Stroke of the ellipse the same color (SolidColorBrush) as the desktop as configured using the control panel).
Complex Properties
Sometimes a property’s value cannot be written as a string and there is no appropriate type converter. For example, a value can be another object that needs to be created. In this case there is a XAML syntax for that. Consider the following XAML that creates a rectangle and rotates it by 30 degrees (from now I’ll omit the XML namespace declarations for brevity):
<Rectangle StrokeThickness="5" Stroke="Red" Fill="Yellow">
<Rectangle.LayoutTransform>
<RotateTransform Angle="30" />
</Rectangle.LayoutTransform>
</Rectangle>
This is the result:

I wanted to set the LayoutTransform property to an instance of RotateTransform class. The format is Type.Property and then the value as a separate element (meaning creating an instance). The equivalent code is something like this:
Rectangle r = new Rectangle();
r.Fill = Brushes.Yellow;
r.Stroke = Brushes.Red;
r.StrokeThickness = 5;
var rt = new RotateTransform();
rt.Angle = 30;
r.LayoutTransform = rt;
The code could be a bit shorter because of a RotateTransform constructor that accepts an angle, but it’s not fundamentally different:
r.LayoutTransform = new RotateTransform(30);
Handling Collections
Some properties are collections. Adding items to collections mean calling some Add method, but XAML in itself cannot call methods. If a property’s type is an IList<T> or IList, the XAML parser will automatically call Add on elements appearing underneath the property. Here’s an example:
<Rectangle StrokeThickness="5" Stroke="Blue">
<Rectangle.Fill>
<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0" Color="Red" />
<GradientStop Offset=".5" Color="Yellow" />
<GradientStop Offset="1" Color="Purple" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
Here’s the result:

A LinearGradientBrush is another type of brush, made of linear gradients. The LinearGradientBrush.GradientStops property is of type GradientStopCollection, which implements IList<GradientStop> (and IList among others). The XAML parser calls Add on each object. The equivalent code might look like this:
Rectangle r = new Rectangle();
r.Stroke = Brushes.Blue;
var brush = new LinearGradientBrush();
brush.GradientStops.Add(new GradientStop(Colors.Red, 0));
brush.GradientStops.Add(new GradientStop(Colors.Yellow, 0.5));
brush.GradientStops.Add(new GradientStop(Colors.Purple, 1));
r.Fill = brush;
Notice how the XAML looks more intuitive (at least after using it for a while…).
The other type of collection supported by XAML is a dictionary (IDictionary implementations). In this case, a key is needed, as Add requires a key and a value. The key is then supplied with the special x:Key attribute on the added element. I’ll show an example of this at a later post.
Content Property
There is another, final, rule to XAML. In the previous LinearGradientBrush example, I’ve set the gradients to the GradientStops property. However, I did not have to actually specify this. I could have gotten away with this:
<Rectangle StrokeThickness="5" Stroke="Blue">
<Rectangle.Fill>
<LinearGradientBrush>
<GradientStop Offset="0" Color="Red" />
<GradientStop Offset=".5" Color="Yellow" />
<GradientStop Offset="1" Color="Purple" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
It looks like the gradient stops are direct children of the LinearGradientBrush. That’s possible because the GradientStops property is identified as the “Content” property of the LinearGradientBrush (you can think of that as a kind of “default” property). So, this code and the previous one are completely equivalent.
How does the XAML parser know this? Again, using an attribute. The GradientBrush abstract class (which is the base of LinearGradientBrush) is declared like this:
[ContentProperty("GradientStops")]
public abstract class GradientBrush : Brush {
That means, that the GradientStops property is the default property in XAML of GradientBrush objects. That’s why it’s permissible (and intuitive) to just specify the property’s value (in this case a collection, but really can be anything). Naturally, every class can have at most one Content property.
Summary: XAML Rules
These are all XAML rules. With that in place, you can read and XAML, no matter its apparent complexity. Here’s the bulleted list:
- An Element means creating an instance
- An attribute means setting a property
- If a type converter exists, it’s invoked
- If it’s a markup extension, it’s invoked
- A property of type IList or IDictionary is automatically treated correctly and objects are added to the collection
- A class can have a single ContentProperty that does not have to be specified in XAML when setting its value.
In the next part, we’ll see how this integrates with Visual Studio and talk some more on why should we want to use XAML.