Avalonia's MVVM template already prepares the structure: Views and ViewModels folders, a ViewLocator that automatically pairs each ViewModel with its view, and compiled bindings enabled by default.
Compiled bindings
With compiled bindings the XAML compiler checks that every property really exists in the ViewModel: a typo becomes a build error, not an empty field discovered by the user.
<PropertyGroup>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
</PropertyGroup>
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:Warehouse.ViewModels"
x:Class="Warehouse.Views.ItemsView"
x:DataType="vm:ItemsViewModel">
<DockPanel Margin="16">
<TextBox DockPanel.Dock="Top" Watermark="Search..." Text="{Binding Filter}" />
<ListBox ItemsSource="{Binding Items}" SelectedItem="{Binding Selected}">
<ListBox.ItemTemplate>
<DataTemplate x:DataType="vm:ItemRow">
<TextBlock Text="{Binding Description}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
</UserControl>
The ViewModel
public partial class ItemsViewModel(ICatalog catalog) : ViewModelBase
{
[ObservableProperty]
public partial string Filter { get; set; } = "";
[ObservableProperty]
public partial ItemRow? Selected { get; set; }
public ObservableCollection<ItemRow> Items { get; } = [];
partial void OnFilterChanged(string value) => _ = RefreshAsync(value);
private async Task RefreshAsync(string filter)
{
var results = await catalog.SearchAsync(filter);
Items.Clear();
foreach (var r in results) Items.Add(r);
}
}
CommunityToolkit.Mvvm works with Avalonia exactly as with MAUI and WPF: the generated On...Changed partial methods let you react to property changes. Alternatively, the template also offers ReactiveUI, widely used in the Avalonia ecosystem.
Navigating between views
A main ViewModel exposes a property holding the current ViewModel; a ContentControl displays it and the ViewLocator picks the right view. Changing screen just means changing that object.
Comments (0)
No comments yet.