Data binding is an excellent feature of the MVVM pattern and allows you to decouple views and view models. Because Xamarin.Forms are MVVM-first, using data binding is a clear choice. However, as data binding uses reflection by default, it can have a negative impact on performance. Luckily, Xamarin.Forms support Compiled Bindings, which are akin to UWP's x:Bind
and let the compiler process all bindings during compile-time and then use strongly-typed references at runtime thus improving performance immensely.
The case for compiled bindings
The first question you may ask is "Is it worth the effort?" And the answer is a resounding "Yes!". Consider the following advantages of using compiled bindings over classing data binding:
- Performance is significantly better - for
OneTime
bindings, the resolution is approximately 20 times quicker for compiled bindings, with other modes still 8 times faster, this improvement can really be felt with larger XAML pages with many controls. - Compile-time confidence - setting up data binding is error-prone, and a simple typo can cause the binding not to work at all and is hard to debug. With compiled bindings, any issue is discovered immediately during compilation so you can be confident that your bindings are (at least referentially) correct. Compiled bindings also help you find out "orphan" bindings that were created previously, but are no longer in use as their bound properties have been removed.
How to
There are two general steps to get compiled bindings working on your XAML page or view:
- Enable XAML compilation using attributes
- Set
x:DataType
to appropriate type on an element in your XAML visual tree
If you created your project from the new built-in Visual Studio Xamarin.Forms templates, the likelihood is you can already cross out the first step on the list - XAML compilation is on by default. Otherwise you can turn this setting on either on the assembly level or on the page level. If you want to automatically enable it for all XAML pages and views in the project (which is recommended), you can do so like this:
You can put this attribute anywhere in the root assembly namespace. A good place would be App.xaml.cs
. Alternatively, you can enable it selectively on page level:
The second step is to enable compiled bindings by adding the x:DataType
attribute to a VisualElement
in XAML. The recommendation is to set the attribute on the same level in the view hierarchy as where the BindingContext
is set. We need to declare an appropriate XML namespace and then use it in the x:DataType
attribute. Suppose your app's name is MyAwesomeApp
and you want to create compiled binding to a simple MyAwesomeApp.ViewModels.HomeViewModel
class:
In HomePage.xaml
we add xmlns:viewModels
declaration with the namespace to the root <ContentPage>
element and set x:DataType
on the same level as well:
The compiled bindings are now up and running on our page. You can verify this by replacing Greeting
in the binding by some non-existent property name and building the project. You will be "greeted" with a clear no-go error message:
Using compiled bindings with DataTemplate
Another perfect place for compiled bindings are list controls, where every little performance improvement counts N-times. Luckily, Xamarin.Forms will not leave you in the cold here either - you can just as easily apply the x:DataType
attribute to DataTemplate
as well:
Switching back to classic bindings
Even though compiled bindings are mature enough for production, you might still encounter some issues. In such cases, you can also selectively disable compiled bindings at any level of the XAML hierarch by setting the x:DataType
attribute back to null
:
Source code
Example source code for this article is available on my GitHub.
Summary
Compiled bindings bring two great advantages over classic bindings in Xamarin.Forms - vast performance upgrade and compile-time checking of bingings. This will definitely improve your developer productivity so enabling them is a smart choice.