Avalonia UI – How to bind to direct properties of a user control within the user control itself

Published:

Modified:

Introduction

Avalonia UI has powerful data binding mechanism. Avalonia UI allows us to reuse our code by creating custom user controls. So what’s the problem?! The problem is that, for beginners, using data binding within their user controls is not straightforward. This article explains how this is done.

Source Code

The complete source code is available in my GitHub repository.

The source code shows how to:

The source code will teach you how to:

Typical beginner approach (does not work)

When creating a user control, this is the typically scenario:

User Control – Code Behind

In our simple code behind, we simply have one simple direct property:

public static readonly DirectProperty<BindableUserControl, string> GreetingProperty = 
	AvaloniaProperty.RegisterDirect<BindableUserControl, string>(
		nameof(Greeting), 
		o => o.Greeting, 
		(o, v) => o.Greeting = v
	);

private string greeting;
public string Greeting
{
	get => greeting;
	set => SetAndRaise(GreetingProperty, ref greeting, value);
}

User Control – XAML – Defining user control

There are 2 important things to mention here:

<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
			 
			 xmlns:ctrl="clr-namespace:Monsalma_AvaloniaUserControlBinding.Controls"
			 
             x:Class="Monsalma_AvaloniaUserControlBinding.Controls.BindableUserControl"
			 x:DataType="ctrl:BindableUserControl"
			 Name="BindableUserControl1">

User Control – XAML – Bind to user control by name

To bind to our custom user control from the control itself, we can use the ElementName (WPF/UWP style) or the name prefix character (#).

WPF/UWP style – ElementName

<TextBlock
	Text="{Binding Greeting, ElementName=BindableUserControl1}" />

Avalonia UI style – Name prefix (#)

<TextBlock
	Text="{Binding #BindableUserControl1.Greeting}" />

User Control – XAML – Bind to user control using ancestor type syntax

There are a few ways to bind to an ancestor:

<TextBlock
	Text="{Binding $parent[ctrl:BindableUserControl].Greeting}" />

User Control – XAML – Bind to user control by setting data context

Our last option is to define DataContext for the TextBlock control. Doing so will override the hierarchical data context, which is MainViewModel in our case, and will allow us to use the simplest form of data binding ({Binding Greeting}). Note that we are referencing the user control by name (Avalonia UI syntax – # prefix).

<TextBlock
	DataContext="{Binding #BindableUserControl1}"
	Text="{Binding Greeting}" />

User control binding in action

For this demo, I chose Windows Desktop and Android as targets. Let’s see the user control data binding in action.

Windows Desktop

Avalonia UI - User Control Data Binding Demo - Windows
Avalonia UI – User Control Data Binding Demo – Windows

Android Emulator – Google Pixel 3 XL (API 30)

Avalonia UI - User Control Data Binding Demo - Android
Avalonia UI – User Control Data Binding Demo – Android

Summary

Avalonia UI is great. Its data binding mechanism is great. Its way of defining user controls is great. I hope this article helps to explain the way data bindings and user controls can be used together.

Leave a Reply

Your email address will not be published. Required fields are marked *