Skip to main content
Version: 11.0.x

Data Binding Syntax

Avalonia supports creating data bindings in XAML and code. Data bindings in XAML are typically created with the Binding MarkupExtension described by this document. To create data bindings in code, see here.

Data Binding MarkupExtension

The Binding MarkupExtension uses the keyword Binding in combination with optional parameters to define the data source and other options as shown by the following example:

<SomeControl SomeProperty="{Binding Path, Mode=ModeValue, StringFormat=Pattern}" />
ParameterDescription
PathThe name of the source property to be bound.
ModeThe synchronization direction of the binding.
PriorityPriority of the property setter.
SourceThe object that contains the Path-specified property.
ElementNameUses a named Control as the Source.
RelativeSourceUses a relative Control within the Visual Tree hierarchy as the Source.
StringFormatA pattern to format the property value as a string.
ConverterAn IValueConverter that converts the source value to the target value and back.
ConverterParameterA parameter to be supplied to the Converter.
FallbackValueSets a value when the binding cannot be created or cannot produce a value.
TargetNullValueSets a value when the source property contains a null value.
UpdateSourceTriggerTriggers a source property update when a predefined condition happens.

These parameters must be known and set at the time of binding creation. They are CLR properties that cannot be set and updated by additional bindings.

Data Binding Path

The first parameter specified is usually the Path. This is the name of a property in the Source (DataContext by default) that Avalonia locates when creating the binding.

You can omit Path= when it is the first parameter. The following two bindings are equivalent:

<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Path=Name}"/>

The binding path can be a single property or a subproperty chain. For example, if the data source has a Student property and the object returned by that property has a property Name, then you can bind to the student's name using syntax like this:

<TextBlock Text="{Binding Student.Name}"/>

If the data source can be indexed (such as an array or list), then you can add the index to the binding path like this:

<TextBlock Text="{Binding Students[0].Name}"/>

Empty Binding Path

You can specify data bindings without a Path. This binds to the DataContext of the Control itself (where the binding is defined). These two syntaxes are equivalent:

<TextBlock Text="{Binding}" />
<TextBlock Text="{Binding .}" />

Data Binding Mode

You can change the direction(s) data is synchronized by specifying the Mode.

For example:

<TextBlock Text="{Binding Name, Mode=OneTime}" />

The available binding modes are:

ModeDescription
OneWayChanges in the data source propagate to the binding target.
TwoWayChanges in the data source propagate to the binding target and vice-versa.
OneTimeThe value from the data source is propagated at initialization to the binding target, but subsequent changes are ignored.
OneWayToSourceChanges in the binding target propagate to the data source, but not the other way.
DefaultThe binding mode is based on a default mode defined in the code for the property. See below.

When no Mode is specified, the Default is used. For a control property that does not change value due to user interaction, the default mode is generally OneWay. For a control property that does change value due to user input, the default mode is usually TwoWay.

For example, the default mode for a TextBlock.Text property is OneWay, and the default mode for a TextBox.Text property is TwoWay.

Data Binding Sources

The Source specifies the root object instance that the Path is relative to. By default, this is the DataContext of the containing Control. The most common scenario involves binding to another control using ElementName or RelativeSource parameters or with their shorthand syntax as part of the Path (#controlName and $parent[ControlType] respectively).

<TextBox Name="input" />
<TextBlock Text="{Binding Text, ElementName=input}" />
<TextBlock Text="{Binding #input.Text}" />

<TextBlock Text="{Binding Title,
RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" />
<TextBlock Text="{Binding $parent[Window].Title}" />
info

For more details on how to bind to controls, see here

Converting Bound Values

Bindings offer multiple approaches to convert or substitute the value supplied by a data binding into a type or value that is more appropriate for the target property.

String Formatting

You can apply a pattern to a OneWay binding to format the bound source property as text via the StringFormat parameter which uses string.Format internally.

The pattern index is zero-based and must be inside curly braces. When the curly braces are at the beginning of the pattern, even when also inside single quotes, they must be escaped. Escaping is done by adding an empty pair of curly braces at the front of the pattern or a backslash on each brace.

<TextBlock Text="{Binding FloatProperty, StringFormat={}{0:0.0}}" />

Alternatively, you can use backslashes to escape the curly brackets needed for the pattern. For example:

<TextBlock Text="{Binding FloatProperty, StringFormat=\{0:0.0\}}" />

However, if your pattern does not start with a zero, you do not need the escape. Also, if you have whitespace in your pattern, you must surround it with single quotes. For example:

<TextBlock Text="{Binding Animals.Count, StringFormat='I have {0} animals.'}" />

Notice that this means that if your pattern starts with the value that you are binding, then you do need the escape. For example:

<TextBlock Text="{Binding Animals.Count, 
StringFormat='{}{0} animals live in the farm.'}" />

String Formatting with Multiple Parameters

MultiBinding can be used to format a string that requires multiple bound parameters. The example below formats multiple numeric inputs as a single string to be displayed.

<StackPanel Spacing="8">
<NumericUpDown x:Name="red" Minimum="0" Maximum="255" Value="0" FormatString="{}{0:0.}" Foreground="Red" />
<NumericUpDown x:Name="green" Minimum="0" Maximum="255" Value="0" FormatString="{}{0:0.}" Foreground="Green" />
<NumericUpDown x:Name="blue" Minimum="0" Maximum="255" Value="0" FormatString="{}{0:0.}" Foreground="Blue" />

<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="(r: {0:0.}, g: {1:0.}, b: {2:0.})">
<Binding Path="Value" ElementName="red" />
<Binding Path="Value" ElementName="green" />
<Binding Path="Value" ElementName="blue" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>

FormatString is used internally by NumericUpDown to change how its value is displayed. Here, because RGB colors are integers, we should not display the decimal portion so 0. is supplied as a custom numeric format specifier that .NET understands.

If the values for the inputs are red = 100, green = 80, and blue = 255, then the text displayed will be (r: 100, g: 80, b: 255).

tip

An alternative is to use an InlineCollection of Run elements each with their own single parameter binding. This allows visual customization of each segment. See the example here

Built-in Conversions

Avalonia has a range of built-in data binding converters. These include:

  • Null-testing converters
  • Boolean operation converters
info

For a listing of Avalonia built-in data binding converters, see the reference here.

Custom Conversions

If the built-in converters do not meet your requirements, then you can create a custom converter by implementing IValueConverter.

info

For guidance on how to create a custom converter, see here.

FallbackValue

FallbackValue is used when the property binding cannot be made or when a converter returns AvaloniaProperty.UnsetValue.

A common use case is when a parent property in a subproperty binding is null. If Student is null below, the FallbackValue will be used:

<TextBlock Text="{Binding Student.Name, FallbackValue=Cannot find name}"/>
tip

ReflectionBinding can bind to arbitrary types without regard to compile-time safety. When the binding cannot be made, FallbackValue may be useful to substitute a value.

TargetNullValue

When a binding to a property is successfully created and the property value is null, TargetNullValue may be used to supply a specific value.

<StackPanel>
<NumericUpDown x:Name="number" Value="200" />
<TextBlock Text="{Binding #number.Value, TargetNullValue=Value is null}" />
</StackPanel>

UpdateSourceTrigger v11.1

Controls like TextBox will synchronize their Text binding to the source property on every keystroke by default. In some use cases, this may trigger a long-running task or undesirable validation. UpdateSourceTrigger allows bindings to specify when synchronization should happen.

UpdateSourceTriggerDescription
DefaultThis currently defaults to PropertyChanged.
PropertyChangedUpdates the binding source immediately whenever the binding target property changes.
LostFocusUpdates the binding source whenever the binding target element loses focus.
ExplicitUpdates the binding source only when you call the BindingExpressionBase.UpdateSource() method.
<StackPanel>
<TextBox Text="{Binding #propertyChanged.Text}" />
<TextBlock Name="propertyChanged" />

<TextBox Text="{Binding #lostFocus.Text, UpdateSourceTrigger=LostFocus}" />
<TextBlock Name="lostFocus" />
</StackPanel>