I just started learning Avalonia and I'm wondering how to create a button that reroutes me from a view to another.
I have the first view titled ValueSelectionPageView and I want to add a button to it that reroutes me to view titled TextPageView
Code for ValueSelectionPageView.axaml:
<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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaApplication1.Views.ValueSelectionPageView"
xmlns:vm="using:AvaloniaApplication1.ViewModels"
x:DataType="vm:ValueSelectionPageViewModel"
>
</UserControl>
TextPageView.axaml:
<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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaApplication1.Views.TextPageView"
xmlns:vm="using:AvaloniaApplication1.ViewModels"
x:DataType="vm:TextPageViewModel"
>
<StackPanel Spacing="10">
<StackPanel.Styles>
<Style Selector="TextBlock">
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="HorizontalAlignment" Value="Center"></Setter>
</Style>
</StackPanel.Styles>
<TextBlock>Hello and Welcome to the text page you can choose the border width below</TextBlock>
<TextBox Width="150" Watermark="Enter something" Text="{Binding ThicknessValue}"></TextBox>
<Button HorizontalAlignment="Center" Command="{Binding ChangeTextCommand}"> CLICK ME</Button>
<Border Margin="0,50,0,0" Width="200" Background="{DynamicResource SystemAccentColorDark1}" BorderBrush="{DynamicResource SystemAccentColor}" BorderThickness="{Binding DefaultThickness}" CornerRadius="8" Padding="16">
<TextBlock>Border</TextBlock>
</Border>
</StackPanel>
ValueSelectionPageViewModel.cs:
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace AvaloniaApplication1.ViewModels;
public class ValueSelectionPageViewModel : ViewModelBase
{
}
TextPageViewModel.cs:
using System;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace AvaloniaApplication1.ViewModels;
public partial class TextPageViewModel : ViewModelBase
{
[ObservableProperty]
private string _thicknessValue = "";
[ObservableProperty]
private string _defaultThickness = "7";
[RelayCommand]
private void ChangeText()
{
DefaultThickness = ThicknessValue;
}
}
I'm also learning, so if anyone has a better way to do this I'm all ears. However, the thing to think about here is the Data Context https://docs.avaloniaui.net/docs/basics/data/data-binding/data-context
When you're changing the views from one to the other, what you're trying to do is change the content binding in the parent View from one Child View to another Child View.
I created a new Avalonia UI MVVM project and added your Views and ViewModels, and then updated the MainWindow.axaml to this
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:TestAvaloniaApp.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="TestAvaloniaApp.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Icon="/Assets/avalonia-logo.ico"
Title="TestAvaloniaApp">
<Design.DataContext>
<!-- This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
<vm:MainWindowViewModel/>
</Design.DataContext>
<ContentControl Content="{Binding CurrentView}"></ContentControl>
In the MainWindowViewModel I have this
using CommunityToolkit.Mvvm.ComponentModel;
namespace TestAvaloniaApp.ViewModels;
public partial class MainWindowViewModel : ViewModelBase
{
#pragma warning disable CA1822 // Mark members as static
public string Greeting => "Welcome to Avalonia!";
[ObservableProperty]
private ViewModelBase _currentView = new ValueSelectionPageViewModel();
public void ChangeView()
{
TextPageViewModel textPageViewModel = new();
CurrentView = textPageViewModel;
}
#pragma warning restore CA1822 // Mark members as static
}
Finally, I updated the ValueSelectionPageView to contain this
<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:viewModels="using:TestAvaloniaApp.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="TestAvaloniaApp.Views.ValueSelectionPageView"
x:DataType="viewModels:ValueSelectionPageViewModel">
<StackPanel>
<Button x:CompileBindings="False"
Command="{Binding $parent[Window].DataContext.ChangeView}"> Click Me</Button>
</StackPanel>
The important part is noticing the $parent[Window].DataContext.ChangeView
. This allows you to call the ChangeView() method of the Main Window to update the <ContentControl>
to the new view.