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}" />
Parameter | Description |
---|---|
Path | The name of the source property to be bound. |
Mode | The synchronization direction of the binding. |
Priority | Priority of the property setter. |
Source | The object that contains the Path -specified property. |
ElementName | Uses a named Control as the Source . |
RelativeSource | Uses a relative Control within the Visual Tree hierarchy as the Source . |
StringFormat | A pattern to format the property value as a string. |
Converter | An IValueConverter that converts the source value to the target value and back. |
ConverterParameter | A parameter to be supplied to the Converter . |
FallbackValue | Sets a value when the binding cannot be created or cannot produce a value. |
TargetNullValue | Sets a value when the source property contains a null value. |
UpdateSourceTrigger | Triggers 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:
Mode | Description |
---|---|
OneWay | Changes in the data source propagate to the binding target. |
TwoWay | Changes in the data source propagate to the binding target and vice-versa. |
OneTime | The value from the data source is propagated at initialization to the binding target, but subsequent changes are ignored. |
OneWayToSource | Changes in the binding target propagate to the data source, but not the other way. |
Default | The 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}" />
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)
.
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
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
.
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}"/>
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 Preview!
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.
UpdateSourceTrigger | Description |
---|---|
Default | This currently defaults to PropertyChanged . |
PropertyChanged | Updates the binding source immediately whenever the binding target property changes. |
LostFocus | Updates the binding source whenever the binding target element loses focus. |
Explicit | Updates 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>