Saturday, January 26, 2008

XAML

When I talk to developers about WPF, inevitably questions about XAML comes up. How can we avoid looking at the XAML? Are the designers ready yet? To me, those are the wrong questions. A better question is: should we avoid working directly in XAML? I want to give my answer to that question in this post.

Firstly, it's important to realize that WPF and XAML are not one and the same. XAML is just a convenient format for defining a user interface. At the end of the day, it's just a dialect of XML that can encode a hierarchy of CLR objects. There's no reason those CLR objects have to be WPF types.

This confusion probably stems from the fact that XAML is shipped with WPF, and the XAML support classes like XamlReader and XamlWriter are contained inside a WPF assembly (PresentationFramework.dll). I think this is unfortunate, but it does not mean that use of XAML implies a WPF interface (or any interface at all).

To demonstrate this, I put together the project linked at the bottom of this post, which shows XAML being used to encode a simple Windows Forms user interface:

image

It's important to realise that while XAML isn't WPF-specific, WPF does make efforts to ensure that it provides a good XAML experience. For example, all WPF types that you might want to create within XAML have default constructors. And the [ContentPropertyAttribute] has been applied where relevant. WPF also provides a number of XAML markup extensions to integrate with WPF's data binding and resource system, among other things.

Just as you can use XAML outside of WPF, you can also do WPF without XAML. There's no reason you can't construct and wire together your user interface widgets yourself, or perhaps use some other third party designer that writes the code for you. You could even invent your own format for encoding the control tree. At the end of the day, you just need to end up with a tree of controls at runtime - XAML is one way to define that tree. But is it a good way?

To my mind, there are two kinds of XAML: I'll call them functional and aesthetic. Functional XAML is the basic layout of your UI and any supporting bindings / business logic. Aesthetic XAML consists of styles and templates, which are used to give your UI a look and feel. Functional XAML is what you, as a developer, want to be working with. The aesthetic XAML is best left to designers and UX guys, which counts out most developers.

But here's the thing: the two types of XAML can be separated. Developers can work directly in the minimalist, functional XAML and leave the verbose, aesthetic XAML to the designers. Designers can use Expression tools to maintain the aesthetic XAML.

This debunks one of the biggest complaints about XAML: "it's too verbose". Sure, it's verbose if you try and lump everything into the same file, but if you separate concerns you will end up with the digestible, functional XAML in one file and the verbose, tool-able aesthetic XAML in others.

It also goes to show just how soluble functional XAML can be once you prune out the aesthetic XAML. I'd wager that even non-developers could understand the general gist of this XAML:

<Window x:Class="MyApplication.LoginWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Label>User Name:</Label>
        <TextBox Grid.Column="1" Text="{Binding UserName}"/>

        <Label Grid.Row="1">Password:</Label>
        <PasswordBox Grid.Row="1" Grid.Column="1" x:Name="_passwordBox"/>

        <StackPanel Grid.Row="2" Grid.ColumnSpan="2" Orientation="Horizontal">
            <Button>_OK</Button>
            <Button>_Cancel</Button>
        </StackPanel>
    </Grid>
</Window>

To me, this is very readable, and web developers would find the declarative syntax familiar. The indentation makes the hierarchical relationships between controls obvious, and the well-named WPF types make the contents of the tree obvious. However, in the above example, the use of the very generic Grid panel introduces a certain amount of noise. Fear not, because that could be eliminated with a custom control:

<Window x:Class="MyApplication.LoginWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <FieldValuePanel>
        <Label>User Name:</Label>
        <TextBox Text="{Binding UserName}"/>

        <Label>Password:</Label>
        <PasswordBox x:Name="_passwordBox"/>

        <StackPanel Orientation="Horizontal" FieldValuePanel.Stretch="True">
            <Button>_OK</Button>
            <Button>_Cancel</Button>
        </StackPanel>
    </FieldValuePanel>
</Window>

That's even cleaner, and we could go even further if we wanted to.

Suppose we'd like to right-align the StackPanel. Would you rather insert a simple HorizontalAlignment="Right" in the XAML, or try and do it in the designer:

image

I know what I'd prefer, especially when the designer can end up doing all sorts of nasty things to your XAML:

        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" MinHeight="26.146" />
            <RowDefinition Height="Auto" MinHeight="26.146" />
            <RowDefinition Height="Auto" MinHeight="22.301" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="51.523*"/>
            <ColumnDefinition Width="19.847*" />
            <ColumnDefinition Width="13.073*"/>
        </Grid.ColumnDefinitions>

        <Label Height="17.687" VerticalAlignment="Top">User Name:</Label>

One of the benefits to the designer is that it gives you a preview of your visual tree. That is certainly useful at times, but it doesn't mean you have to use the designer to do editing. You could just split the screen between XAML and designer:

image

Or you could use a tool like Kaxaml.

So, back to the question: should we avoid working directly in XAML? I think developers should be embracing XAML, and rejoicing in the fact that we no longer have to wrestle with designers. With some good techniques like separation of concerns, XAML becomes very soluble and a boon to productivity.

5 comments:

Anonymous said...

Just clarification: the only way to create template (ControlTemplate, DataTemplate) is Xaml. C# analog (FrameworkElementFactory) is too limited. So Xaml is mandatory part of WPF.

Kent Boogaart said...

Thanks anon - that is interesting indeed. I wonder whether this will be rectified in a future WPF release. It seems odd and - frankly - wrong that something possible in XAML is not possible in direct code.

Thanks again,
Kent

Rob Relyea said...

Yes, we would have preffered to have not even haved shipped FEFs (FrameworkElementFactories).
We are planning to address this so that templates are fully programmable and as powerful as creating them in Xaml is...

Thanks, Rob Relyea
WPF/Xaml Language Teams

ghkj said...

This momentousdecree wow gold came as a great beacon gold in wow light of hope buy wow gold to millions of negroslaves wow gold kaufen who had been seared in the flames of withering injustice.maplestory mesos it came as a joyous daybreak to end the long night ofcaptivity.but one hundred years later,maplestory money we must face the tragic fact thatthe negro is still not free.maple money one hundred years later,sell wow gold the lifeof the negro is still sadly crippled by the manacles ofsegregation and the chains of discrimination. one hundred yearslater,maple story money the negro lives on a lonely island of poverty in themidst of a vast ocean of material prosperity.wow powerleveling one hundred yearslater,maple story power leveling the negro is still languishing in the corners of americansociety and finds himself an exile in his own land. so we havecome here today to dramatize wow powerleveln an appalling condition.in a ms mesos sense we have come to our nation''s capital to cash a check.when the architects of our republic wow powerleveln wrote the magnificent wordsof the constitution and the declaration of independence, theywere signing a promissory note maplestory power leveling to which every american was tofall heir.

Anonymous said...

I know this is an old post but some of are the era before designers and realize just why designers were developed in the first place.

Of course there advantages to update xaml directly, but I think its a huge step backwards from languages like C# or Java.

The problem is the same: once people get used to whatever they do, they resist change. HTML sucks and XAML sucks, but now that so many people have been ingrained, they just follow the crowd.

There is a reason WPF isn't gathering steam: it sucks to work with.