In previous installments to this series of XAML Anti-Pattern articles, I discussed coding techniques and patterns in XAML-based UIs (WPF, WinRT, Windows Phone, etc.) that lead to problems. You've already discovered that in XAML, it isn't always easy to decide when a certain technique has a positive impact and when it backfires. The concepts discussed in this article are another variation on the same theme. Creating UIs out of a combination of XAML and C# or VB code is certainly a good idea that's fundamentally sound. But the big question is how to take advantage of this basic idea without creating an unmaintainable and costly monstrosity.

When creating XAML-based UIs, the default setup is for a XAML file with an associated code-behind file (typically written in C# or VB). Technically speaking, the two different files are “partial classes” written in two different languages (XAML and C#/VB) that create a single class which can then be used like any other class. For instance, the following code snippet is the default main window created by a new WPF project (namespaces truncated for readability):

<Window x:Class="CodeBehind.MainWindow"
        xmlns="http://schemas.microsoft.com/...";
        xmlns:x="http://schemas.microsoft.com/...";
        Title="MainWindow" Height="350" Width="525">
    <Grid>
    </Grid>
</Window>

This includes an x:Class setting, which ties the XAML to the C# class definition (or VB, if that's the language of choice for you) in a code-behind file. Here's what that looks like:

using System.Windows;

namespace CodeBehind
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

The resulting class can then be instantiated like any other .NET type:

var window = new MainWindow();

The advantage of this set up is that you can use the convenient XAML language to declare which interface elements are to appear, yet use imperative coding techniques in the C# file to code the logic. For instance, you can add a button to the UI in XAML and fire associated code in C# like this:

<Button Click="Hello">
    <TextBlock FontSize="48">
        <Run FontWeight="Bold">Hello </Run>
        <Run FontStyle="Italic">World</Run>
    </TextBlock>
</Button>

The associated C# looks like this:

private void Hello(object sender, RoutedEventArgs e)
{
    if (DateTime.Now.Hour < 12)
        MessageBox.Show("Good morning!");
    else
        MessageBox.Show("Hello!");
}

As you can see, defining a button with a richly formatted caption is convenient and natural in XAML. Imagine, by comparison, what you'd have to do in C# to define a button like that. On the other hand, writing any kind of flow-logic in a declarative markup language would be a nightmare and C# is much better suited for the task. The combination of the two is great and fundamentally sound. So why, then, am I writing an anti-pattern article about this technique?

Code-behind files are a big part of the reason some developers perceive XAML as a difficult and unproductive environment.

The Problem with Code-Behind

As is the case in the XAML anti-pattern scenarios that I've discussed in previous articles, things aren't always black and white and the utility of a certain approach or technique depends significantly on each scenario. Although the fundamental idea of combining XAML and C# isn't bad, the devil's in the details. Let's spin the example a little bit further, and say you want to use different UI elements for the same feature-set. This is a relatively common scenario in modern UIs where, over time, UI styles change drastically and new features have to be added without being able to re-write the whole UI and re-test the UI logic. UI styles and form factors tend to change very rapidly, making changes a common and expensive issue. In today's software development landscape, inefficient and expensive UI techniques have simply become unacceptable.

To illustrate the point, let's assume that a requirement has come your way that says that the user is now also supposed to be able to trigger the Hello() functionality by means of a context-menu. This, in itself, isn't a difficult requirement, and you can add such a menu to the window easily:

<Window.ContextMenu>
    <ContextMenu>
        <MenuItem Header="Hello" Click="Hello"/>
    </ContextMenu>
</Window.ContextMenu>

You simply add a new menu item and wire the click-event up to the same method, and voila, you're ready to go.

However, when you take a closer look at this, you'll discover that you dodged a bullet! You used the Click event of the MenuItem class and pointed it to the existing Hello() event handler method. For this to work, that method has to have a matching signature. As luck would have it, there's a match and so everything worked just fine. In many scenarios, this isn't the case. Imagine, for instance, that the requirement was to add touch-support to the UI and, as a result, you might want to tie a certain touch-gesture to this method. At that point, you couldn't use the Hello() method anymore, because its signature doesn't match that event's requirements. A similar example would be that of a specific key-press that's meant to trigger the same method. You couldn't use key-bindings, nor any of the key-press events, because their signature doesn't match what you currently have.

I've only scratched the surface of the problem definition, but you've already encountered show-stopper issues that aren't supported by the current architecture. To enable either the key-press or the touch-gesture scenarios, you need to add new event handler methods in the code-behind files. You should probably also refactor the existing method into a more generic method that can then be called from the different event handlers, so at least you have only one method that performs the actual logic and all the different event handlers become relatively trivial plumbing methods that call into the method you're actually after.

Using this approach, things work. They're very messy, but they work. What isn't immediately obvious from this example but is implied, is that everything you've created so far is quite specific to the environment you're operating in. I started this example with the WPF template and I've used all WPF-specific code. Conceptually, it could all apply to other environments as well, such as Windows Phone or Windows Store apps. Those scenarios certainly support UIs with buttons, and the logic you put into your C# file could work unchanged. You've tied yourself to WPF for petty technical reasons. For instance, the event handler signatures are WPF-specific. The differences may not be huge at this point, but in larger real-world applications, this kills asset-reuse across these platforms entirely.

This code is truly horrible! You're practically declaring XAML UI bankruptcy.

Of course, the real world is rather more complex than this scenario has shown so far. In particular, user interface development isn't a one-way street from XAML to C#; things move both ways. Not only does the UI have to trigger code, but code has to influence UI behavior. For instance, code may drive whether or not the UI element should be enabled. Perhaps the Hello() method should only be available during business hours. Of course, you could bake such a check into the method itself (and probably should), but to provide a good UI experience, you need to enable and disable UI elements. Now things get dicey, because the C# code needs to know about the specifics of the XAML UI. One solution is to assign names to the UI elements and then access them from C# like this:

if (DateTime.Now.Hour < 8 || DateTime.Now.Hour > 18)
{
    Button.IsEnabled = false;
    Menu.IsEnabled = false;
}

This code is truly horrible! You have completely killed flexibility at this point. You can't change UI elements without breaking the code. The code is now hard-wired to the existing UI (try unit testing that code on its own!). You've lost the ability to change the UI elements over time or for different scenarios and themes (such as mouse versus touch operation). And for what? To perform the “amazing” task of enabling or disabling a button?!? This is unacceptable.

One of the great advantages of XAML technology is the great degree of flexibility and reuse. Applying proper code-reuse and styling techniques, you can create XAML UIs quite productively (see sidebar) and easily maintain and change the UI over time as needs and requirements evolve. For instance, using the CODE Framework (see sidebar), it's possible to create applications that switch between various themes, ranging from Office look and feel to Metro-style touch UIs and many others. But this requires that View-Models don't hard code dependencies in the UI layer. By abandoning loose-coupling between the View-Model and the XAML, you're immediately giving up on this benefit. You're practically declaring XAML UI bankruptcy.

These are just a few very examples to illustrate the basics of the problem. In short: Although it's good to combine XAML and C#/VB code, it's awful to hardwire the two together in the fashion demonstrated here. It kills reuse. It kills maintainability. It kills flexibility and the ability to evolve your application over time. It causes a lot of extra work and effort and it's poison to preserving your investment. It incurs technical debt.

It only gets worse, the larger the scenarios get.

A Simple Solution

The good news is that XAML technologies make it simple to fix this problem. Not only that, but the solution generally also requires less code and is faster and more productive to develop. It ends up with more maintainable code that often also performs better.

When it comes to code-behind for XAML UIs, all of the code you create follows a few simple and repetitive patterns. You stick data into the UI. You react to events. You add behavior. All XAML dialects provide an abstract means of handling these things without introducing tightly coupled code-behind scenarios. As a result, you can still enjoy the benefits of using C# and XAML together without the downsides. You're still putting code behind the XAML UIs, but it's a better way of creating the link.

You're still putting code behind the XAML UIs, but it's a better way of creating the link.

Although it isn't strictly required, a good starting point is the adoption of the “View/View-Model” pattern. In other words, write your visual UI elements in XAML. Then, write an object that represents all the data and logic that's going on in the UI, but in a non-visual and somewhat abstract fashion. Then couple the two together. It's relatively simple. In fact, contrary to popular belief, it's a simplification of UI development.

Let's start with the View-Model, which could looks something like this:

public class HelloViewModel
{
    public HelloViewModel()
    {
        HelloCommand = new ViewAction(o => Hello(),
                                      o => CanSayHello());
    }

    public ICommand HelloCommand { get; set; }

    public bool CanSayHello()
    {
        return (DateTime.Now.Hour < 8 || DateTime.Now.Hour > 18);
    }

    public void Hello()
    {
        if (!CanSayHello()) return;
        var message = DateTime.Now.Hour < 12 ? "Good morning!" : "Hello!";
        MessageBox.Show(message);
    }
}

As you can see, this class encapsulates all of the functionality you had in the code-behind file. In fact, although it's still quite simple overall, it's a more sophisticated implementation with some extra checks. You have a generic Hello() method. You also have a method that tells you whether it's currently OK to say “hello” (which can be called on its own, but is also called from the Hello() method, just to make sure). You could enhance this a bit further to get rid of things such as the message-box, but that's not important for this example. What is important is that you now have a very generic object that could work in just about any environment, and it conceptually provides everything needed for the UI to function.

The question that remains is how you'll tie this to the UI. How can you generically trigger methods and checks from whatever UI elements you want to use? One answer to this question is the use of Commands. This isn't the right answer for all scenarios (and I'll explore others further down below), but it's a perfect match for the current example. Commands encapsulate what's often done with events, but they're more abstract and provide extra features. Commands have a somewhat undeserved reputation of being cumbersome, but that's not so, especially if you have an implementation of a command ready to go. It's something you do once, or you use a ready-made implementation. (For instance, the free CODE Framework provides a powerful standard implementation of a command). Listing 1 shows the most basic implementation of such a convenience object, called ViewAction. It defines what happens when the command executes, and it optionally allows you to specify a method that checks whether the command can execute at all. The constructor of the snippet just above shows how the ViewAction is instantiated, linked to the Hello() and CanSayHello() methods, and then assigned to a property.

Listing 1: A simple and convenient standard-implementation for a Command object

public class ViewAction : ICommand
{
    private readonly Func<object, bool> _canExecute;
    private readonly Action<object> _execute;

    public ViewAction(Action<object> execute,
    Func<object, bool> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        if (_canExecute == null) return true;
        return _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }

    public event EventHandler CanExecuteChanged;
}

Using this set up, you can now instantiate this View-Model class and assign it as the DataContext of the UI:

DataContext = new HelloViewModel();

With this in place, you can now use this View-Model in your UI elements. All XAML dialects provide a means of binding to commands. Here's an example that shows the menu item bound to the new command:

<MenuItem Header="Hello" Command="{Binding HelloCommand}"/>

This wires the menu item to the execute code of the command you created. But it's not only that. It also automatically enables and disables the menu item based on the can-execute-method you defined. All of this is built into all versions of XAML and works straight out of the box.

Keep in mind that the command setup is not tied to a specific event signature as it was when you used the Click event. Instead, you can bind the same command to the button:

<Button Command="{Binding HelloCommand}"/>

You can even tie the same command to a key-stroke:

<Window.InputBindings>
    <KeyBinding Key="H" Command="{Binding HelloCommand}"/>
</Window.InputBindings>

This makes for a very flexible and powerful system that is easy to maintain over time. The code becomes very reusable. Quality control is greatly simplified. And it makes for a faster development approach. You're done writing multiple event-handlers. You can quickly slap together a preliminary UI and then touch it up later without having to change your C# code. It's a pleasant way to develop.

Fancy Property Binding to the Rescue!

At this point, the seasoned XAML developer may point out that commands aren't a solution for everything. And they're absolutely correct. Commands are only a solution for the scenario I presented here. There are many other scenarios that require different approaches. For instance, if you needed to enable or disable a control that doesn't have any action associated with it, you wouldn't bind a command to that control. Imagine a textbox that needs to be disabled based on certain logic. In that case, you'd simply bind properties. The View-Model can provide a Boolean property that indicates an enabled state, and the textbox (or any other control) can bind its IsEnabled property to that View-Model-Property:

<TextBox IsEnabled="{Binding CompanyNameEnabled}"
         Text="{Binding CompanyName}" />

This also works with other properties. Perhaps you want to control visibility, in which case, you can create a matching property on the View-Model (of type Visibility) and bind that:

<TextBox Visibility="{Binding CompanyNameVisibility}"
         Text="{Binding CompanyName}" />

On a side-note, I'm not a big fan of binding converters for a variety of reasons, and that may be the topic of a different article. To make a long story short, I find it easier to develop, easier to test, and often to offer better performance when the View-Model has properties that match what I'm trying to bind.

Properties are a simple way to handle a lot of these things. This is probably something you already knew. And again, this doesn't solve all your problems but it covers a lot of ground.

If this were a lecture rather than an article, we'd have now reached the point where the skeptic in the last row gets a little antsy and comes up with scenarios that I haven't covered so far. At this point, people usually throw scenarios at me that they feel require conventional code-behind files. The most common scenario I hear is one that involves a TreeView (which seems to be the poster-child for a XAML control that people do battle with). A very representative example is this commonly heard nugget: “I want to add a feature that programmatically expands all items in a tree and I can't bind that functionality from a View-Model.” They're right. Triggering this kind of behavior isn't something that works out of the box. You could bind the expanded/collapsed state of an individual tree node relatively easily, but there's no property you can bind to, and there's no command you can use to expand all items in reaction to some condition or event. Guess what: Because you don't have a property to bind, you can simply attach one!

Because you don't have a property you can bind, you can simply attach one!

All XAML dialects offer the concept of “attached properties”. A full exploration of this topic is beyond the scope of this article (I wrote a full article covering that topic for CODE Magazine, May/June 2014), but the basic idea is that you can arbitrarily create properties that get attached to existing objects of any kind without the need to subclass or to have control over the object in any way. The property can be data bound. Most importantly, it can have a change event associated with it that fires whenever the property changes and it provides information about the object the property was set on.

Listing 2 shows the implementation of an attached property called AreAllNodesExpanded. The interesting part is in the AreAllNodesExpandedChanged() method. This method fires whenever the property changes and it passes information about the change. So whenever you set this property to a new value, this method fires in response and gives you the opportunity to react by running any code you want, just like you would in a code-behind event handler.

Listing 2: An attached property used to expand or collapse all nodes in a tree

public class Ex : DependencyObject
{
    public static readonly DependencyProperty
        AreAllNodesExpandedProperty =
        DependencyProperty.RegisterAttached("AreAllNodesExpanded",
        typeof(bool), typeof(Ex), new PropertyMetadata(false,
        AreAllNodesExpandedChanged));

    private static void AreAllNodesExpandedChanged(DependencyObject d,
        DependencyPropertyChangedEventArgs e)
    {
        var tree = d as TreeView;
        if (tree == null) return;

        var isExpanded = GetAreAllNodesExpanded(tree);
        foreach (TreeViewItem node in tree.Items)
            node.IsExpanded = isExpanded;
    }

    public static bool GetAreAllNodesExpanded(DependencyObject d)
    {
        return (bool)d.GetValue(AreAllNodesExpandedProperty);
    }
    public static void SetAreAllNodesExpanded(DependencyObject d, bool value)
    {
        d.SetValue(AreAllNodesExpandedProperty, value);
    }
}

The most important part of the implementation of this method is the first parameter, which is defined as a generic DependencyObject, but during runtime, it's the object the property is set on, which is going to be a TreeView in this example. You can cast that reference and once you have access to the tree itself, you can do anything and everything you want. The code that goes after that is exactly identical with what you'd otherwise put into an event handler. In my example, I expand or collapse all first-level nodes, but those details aren't really important. You can add whatever logic and behavior you desire there. The important part is to understand that there's no difference in the code you can write in an attached property handler compared to a regular code-behind file. It's simply a different way of wiring up code.

There's no difference in what you can do in code wired up generically compared to hard-wired code-behind files.

Now that you've created the attached property, you can put it to good use in your UI:

<TreeView c:Ex.AreAllNodesExpanded="{Binding Expanded}" />

You can also cause all the nodes to expand and collapse using this code within the View-Model:

Expanded = true; // Expands all nodes
Expanded = false; // Collapses all nodes

For details on this implementation, please refer to my article about attached properties (CODE Magazine, May/June 2014). The main takeaway here is how much better this solution is than writing code into a code-behind file. The benefits include better testability of the View-Model. You can reuse the same View-Model for various UIs. Perhaps you use a tree in a Windows Desktop app, and choose a tile-based control in Windows Store apps. Maybe you're using a third-party control. It doesn't matter. You can always provide a simple attached property that allows binding to the same property on your View-Model regardless of the UI components used to represent the items. The abstract concept of “being expanded or collapsed” expressed by the Expanded property of the View-Model easily maps to all these UI elements.

I want to further stress that this is just a simple example. Attached properties can be simple values, or they can be complex objects. It's entirely possible to write very complex behaviors encapsulated into their own object constructs, and then attach entire objects to existing XAML UIs. In fact, Microsoft Expression Blend's behaviors use this very concept. For instance, you can drop a MouseDragElementBehavior onto any UI element, such as a Rectangle or Button, to make the object movable with the mouse. The code created in XAML looks like this:

<Rectangle Fill="Red" Height="100" Width="200">
    <i:Interaction.Behaviors>
        <ei:MouseDragElementBehavior/>
    </i:Interaction.Behaviors>
</Rectangle>

This takes advantage of an attached property called Behaviors with a Type of a collection of behaviors. In this example, it contains one behavior for the mouse-drag functionality. Under the hood, the attached Behaviors property triggers a change when a behavior collection is assigned and, in response, wires up all the required events to perform drag-move operations on the object the behavior is attached to. Isn't this much nicer than having to write all of the required functionality time and time again in a code-behind file only to see the feature broken when relatively minor details change in the UI?

The options are limitless. In my experience, this technique alone solves almost all remaining issues normally addressed by code-behind.

In my experience, this behavior technique alone solves almost all remaining issues.

But then again, maybe there are more issues that can't be addressed by behaviors. In that case, you could subclass the control you're interested in. Or maybe you want to inject an invisible object into the XAML that has all the code you need. I'm not going to spend any time on these techniques here since I find that I never have to go to this extent, but if you encounter the need…. All of these options are better than abandoning all flexibility and reuse by sticking code in a traditional code-behind file.

Conclusion

It has long been clear that code in code-behind files introduces some issues. It appears to be a convenient place to put stuff, and many developers use it like that. It works, but it results in ugly code that's hard to reuse and maintain. The code that's written in code-behind files by all but the most disciplined teams isn't able to adjust nimbly enough to today's requirements for software projects. It's my opinion that nasty constructs in code-behind files are a big part of the reason some developers perceive XAML as a difficult and unproductive development environment.

When my team and I first set out to architect the WPF parts of CODE Framework, it was a goal to eliminate the need for code-behind as much as possible and enable a more productive yet more maintainable and reusable development. CODE Framework has always supported XAML development completely without code-behind files (loose XAML). It also supports the more conventional approach with code-behind files just in case. The original vision was that you should be able to do 80-90% of your development without the need for code-behind. In the end, CODE Framework far exceeds that goal. I haven't used code-behind files in years and I'm not aware of any CODE Framework developers who use them. Remember, this is by choice, not by rule. If anyone has a good scenario to use code-behind files, I'd love to hear about it.