Compiled Data Binding with UWP

Because Microsoft itself is using XAML in many places within Windows, as well as with different Microsoft Office implementations, the Binding markup extension that was used with XAML was not fast enough. A different implementation was needed.
One of the greatest features of XAML with UWP (Universal Windows Platform) apps is compiled data binding. The Binding markup extension makes use of reflection to retrieve values from properties. With compiled binding, C# code gets generated from XAML code to directly access properties. In this article I’ll show the advantages as well as how compiled binding can be used.

Null or Nothing

Compiled Binding

The syntax with compiled binding looks very similar to the Binding markup extension as the following code snippets demonstrated. Instead of using Binding, x:Bind is used:

<TextBox Text="{Binding ViewModel.Book.Title, Mode=TwoWay}" />
<TextBox Text="{x:Bind ViewModel.Book.Title, Mode=TwoWay}" />

The code looks similar, but behind the scenes, the Text property of the TextBox is directly accessed, and the Title property from the book is retrieved on setting the TextBox. Besides being faster, compiled binding also has the advantage that you get compiler errors when not using the correct property names.

Behind the scenes, from the XAML code a method such like the following is generated (simplified, as the generated namespaces with the global scope are removed). Indeed, just the Text property is set for the TextBox.

public static void Set_Windows_UI_Xaml_Controls_TextBox_Text(TextBox obj, string value, string targetNullValue)
{
  if (value == null && targetNullValue != null)
  {
    value = targetNullValue;
  }
  obj.Text = value ?? string.Empty;
}

Using the Binding markup extension, the DataContext is important. To find the object where the binding applies, the hierarchy of the next parent element is searched for that has a DataContext applied. The DataContext no longer applies with compiled data binding. Instead, always the page is bound. That’s why I usually define a ViewModel property with the page that is of type of the view-model. When I’m using both WPF and UWP (which is often the case), with WPF I’m setting the DataContext property of the Window to the ViewModel. This way, there’s a similar behavior with the Binding and the x:Bind markup extensions.

With XAML compiled binding we get compilation errors if the wrong property names are used – a feature that would be great for WPF as well

The default mode of the binding syntax is also different between the two variants. While the Binding markup extension has a default of TwoWay binding with the Text property of the TextBox, the default with compiled binding is always OneTime. Because performance is an important aspect with compiled data binding, the fastest mode is the default. In case you need a different mode such as OneWay or TwoWay, the mode needs to be specified.

It’s best to specify the XAML binding mode explicitely, in special when working with different XAML technologies. Otherwise you’ll be surprised why a binding is not working as expected. This can happen for example if you are used to the defaults to WPF and start writing UWP code.

A collection can be assigned to an ItemsSource in the same way as the Bindng markup extension was used. The SelectedItem property of the ListBox can also be bound to the property SelectedBook. However, because compiled binding is strongly typed, the compilation error Invalid binding path … : Cannot bind type … to ‘System.Object’ without a converter occurs. Setting the converter ObjectToObjectConverter helps:

<ListBox ItemsSource="{x:Bind ViewModel.Books, Mode=OneTime}"
    SelectedItem="{x:Bind ViewModel.SelectedBook, Mode=TwoWay, Converter={StaticResource ObjectToObjectConverter}}">

The converter is just an extremly simple implementation of IValueConverter:

public class ObjectToObjectConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, string language) => value;

  public object ConvertBack(object value, Type targetType, object parameter, string language) => value;
}

Why is it not a good idea to write such code yourself – setting properties instead of data binding? Using data binding we have a separation between the functionality and the UI. This allows for better unit testing, and also separating view-models into shared libraries. Using compiled data binding, these advantages still apply.

Data Templates with Compiled Binding

To define a data template using compiled binding, the type needs to specified with the DataTemplate. Otherwise, the compiler wouldn’t know about the available properties. Specifying the type can be done with the attribute x:DataType:

<ListBox.ItemTemplate>
  <DataTemplate x:DataType="model.Book">
    <StackPanel Orientation="Vertical">
      <TextBlock Text="{x:Bind Title, Mode=OneWay}" />
    </StackPanel>
  </DataTemplate>
</ListBox.ItemTemplate>

Binding to Events

Because compiled binding generates C# code, it is also possible to bind events to methods. Of course, binding commands works as expected:

<Button Content="Load" Command="{x:Bind ViewModel.GetBooksCommand, Mode=OneTime}" />

Binding to events, the Click event binds to the OnChangeBook handler method. This method can have either no arguments, or arguments as specified by the Click event:

<AppBarButton IsCompact="False" Icon="Edit" Label="Change Book" Click="{x:Bind OnChangeBook}" />

Compiled Binding Lifecycle

Often several bound objects change values, and it might not be a good idea to update one after the other in the user interface. Using compiled data binding it is easy to stop tracking of bound objects, and make updates explicitely.
The compiler creates an interface that is implemented from an inner class of the page:

private interface ILifetimeSample_Bindings
{
  void Initialize();
  void Update();
  void StopTracking();
}

This interface is implemented by a class that is referenced using the Bindings property of the page. Invoking the StopTracking method, bindings are no longer updated – until Initialize is called again. With the Update method, bindings are updated – this also allows using auto-properties instead of full properties with change notification.

Summary

Compiled data binding is just like christmas for XAML developers – many wishes are fulfilled. While XAML data binding was already extremly powerful, now we also get compile time errors and have a better performance. Additional it’s easy to control the binding lifetime

Sample code is from my book Professional C# 6 and .NET Core 1.0, see source code on GitHub, chapters Patterns with XAML Apps, and Windows Apps: User Interface.

Have fun with programming and learning!
Christian

More Information

Compiled data binding as well as additional information about XAML with UWP and WPF in my new book and my workshops:

Professional C# 6 and .NET Core 1.0
Programming Apps with the MVVM Pattern
Programming Universal Apps
Programming Desktop Applications with WPF

Compiled data binding connects properties of UI elements to properties or methods in a fast way: image from © Petros Tsonis | Dreamstime.com Fiber cables

4 thoughts on “Compiled Data Binding with UWP

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s