Compiled Bindings
Bindings defined in the XAML are using reflection in order to find and access the requested property in your ViewModel
. In Avalonia, you can also use compiled bindings, which have some benefits:
- If you use compiled bindings and the property you bind to is not found, you will get a compile-time error. Hence you get a much better debugging experience.
- Reflection is known to be slow (see this article on codeproject.com). Using compiled bindings can therefore improve the performance of your application.
Enable and disable compiled bindings
Compiled bindings are not enabled by default. To enable compiled bindings, you will need to define the DataType
of the object you want to bind to first. In DataTemplates
there is a property DataType
, for all other elements you can set it via x:DataType
. Most likely you will set x:DataType
in your root node, for example in a Window
or an UserControl
. From Avalonia version 0.10.12
onward you can also specify the DataType
in the Binding
directly.
You can now enable or disable compiled bindings by setting x:CompileBindings="[True|False]"
. All child nodes will inherit this property, so you can enable it in your root node and disable it for a specific child, if needed.
<!-- Set DataType and enable compiled bindings -->
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:MyApp.ViewModels"
x:DataType="vm:MyViewModel"
x:CompileBindings="True">
<StackPanel>
<TextBlock Text="Last name:" />
<TextBox Text="{Binding LastName}" />
<TextBlock Text="Given name:" />
<TextBox Text="{Binding GivenName}" />
<TextBlock Text="E-Mail:" />
<!-- Set DataType inside the Binding-markup -->
<TextBox Text="{Binding MailAddress, DataType={x:Type vm:MyViewModel}}" />
<!-- We cannot use compiled bindings to bind to methods, so we opt them out for the button -->
<Button x:CompileBindings="False"
Content="Send an E-Mail"
Command="{Binding SendEmailCommand}" />
</StackPanel>
</UserControl>
Starting from Avalonia 11.0-preview5
you can also enable or disable it in whole project:
<PropertyGroup>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
</PropertyGroup>
CompiledBinding-Markup
If you don't want to enable compiled bindings for all child nodes, you can also use the CompiledBinding
-markup. You still need to define the DataType
, but you can omit x:CompileBindings="True"
.
<!-- Set DataType -->
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:MyApp.ViewModels"
x:DataType="vm:MyViewModel">
<StackPanel>
<TextBlock Text="Last name:" />
<!-- use CompiledBinding markup for your binding -->
<TextBox Text="{CompiledBinding LastName}" />
<TextBlock Text="Given name:" />
<TextBox Text="{CompiledBinding GivenName}" />
<TextBlock Text="E-Mail:" />
<TextBox Text="{CompiledBinding MailAddress}" />
<!-- We cannot use compiled bindings to bind to methods, so we use the normal Binding -->
<Button Content="Send an E-Mail"
Command="{Binding SendEmailCommand}" />
</StackPanel>
</UserControl>
ReflectionBinding-Markup
If you have compiled bindings enabled in the root node (via x:CompileBindings="True"
) and you either don't want to use compiled binding at a certain position or you hit one of the known limitations, you can use the ReflectionBinding
-markup.
<!-- Set DataType -->
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:MyApp.ViewModels"
x:DataType="vm:MyViewModel"
x:CompileBindings="True">
<StackPanel>
<TextBlock Text="Last name:" />
<TextBox Text="{Binding LastName}" />
<TextBlock Text="Given name:" />
<TextBox Text="{Binding GivenName}" />
<TextBlock Text="E-Mail:" />
<TextBox Text="{Binding MailAddress}" />
<!-- We cannot use compiled bindings to bind to methods, so we use ReflectionBinding instead -->
<Button Content="Send an E-Mail"
Command="{ReflectionBinding SendEmailCommand}" />
</StackPanel>
</UserControl>