How to use data binding within Avalonia UI user control, i.e. How to bind to user control properties within the user control itself

Published:

Modified:

Introduction

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

Demo Project

This post comes with a minimal demo project. It is super easy to understand. You can access the complete source code on GitHub (Avalonia UI user control binding).

The demo project showcases how to:

You will learn to:

Typical beginner approach (does not work)

When working with user controls, this is the typically scenario:

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);
}

XAML – Define 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">

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

We use ElementName to set data context of the Text binding to our user control. We use Greeting (short for Path=Greeting) to access the direct property:

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

Avalonia UI style – Name prefix (#)

We use name prefix (to access our user control) followed by the name of the direct property:

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

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}" />

XAML – Bind to user control by setting data context

Our last option is to define DataContext for the TextBlock control. Doing so overrides the hierarchical data context, which is MainViewModel in our case, and allows 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 helped 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 *