How to Bind to a Collection
Binding to a collection in Avalonia UI is an effective way to display dynamic data. This guide will demonstrate how to bind an ObservableCollection to a control, like a ListBox or ItemsControl, to show a list of items.
Binding to a Simple ObservableCollection
For a start, consider you have an ObservableCollection<string> and you want to bind it to a ListBox to display a list of string items.
Here's an example ViewModel with an ObservableCollection<string>:
public class ViewModel : ObservableObject
{
private ObservableCollection<string> _items;
public ObservableCollection<string> Items
{
get { return _items; }
set { SetProperty(ref _items, value); }
}
public ViewModel()
{
Items = new ObservableCollection<string> { "Item 1", "Item 2", "Item 3" };
}
}
In your view, you can bind this ObservableCollection to a ListBox like so:
<ListBox ItemsSource="{Binding Items}"/>
Binding to an ObservableCollection of Complex Objects
But what if your ObservableCollection contains complex objects that themselves need to propagate changes? Let's modify our ViewModel to accommodate this scenario.
Consider a Person class:
public class Person : ObservableObject
{
private string _name;
private int _age;
public string Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
public int Age
{
get { return _age; }
set { SetProperty(ref _age, value); }
}
}
And an ObservableCollection<Person> in our ViewModel:
public class ViewModel : ObservableObject
{
private ObservableCollection<Person> _people;
public ObservableCollection<Person> People
{
get { return _people; }
set { SetProperty(ref _people, value); }
}
public ViewModel()
{
People = new ObservableCollection<Person>
{
new Person { Name = "John Doe", Age = 30 },
new Person { Name = "Jane Doe", Age = 28 }
};
}
}
You can bind this ObservableCollection to a ListBox in your view, and use a DataTemplate to specify how each Person should be presented:
<ListBox ItemsSource="{Binding People}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" Margin="0,0,10,0"/>
<TextBlock Text="{Binding Age}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In this scenario, each Person in the list will be displayed with their Name and Age separated by a small margin. If any of items properties change, the ListBox item will automatically update.