Как реализовать постраничную навигацию в Avalonia UI MVVM?

Ссылка скопирована
1 ответ
MainWindow

MainWindow.axaml

<Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="using:MultiPageApp.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="MultiPageApp.Views.MainWindow" x:DataType="vm:MainWindowViewModel" Icon="/Assets/avalonia-logo.ico" Title="{Binding CurrentPage.Title}"> <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> <ContentPresenter Content="{Binding CurrentPage}"></ContentPresenter> </Window>
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Backend-редакция Ответ

В Avalonia UI постраничную навигацию в MVVM обычно делают через главный ViewModel с текущей страницей. View не создаёт страницы напрямую, а привязывается к свойству CurrentPage. Для каждого PageViewModel задаётся DataTemplate, который показывает нужный UserControl.

Пример MainWindow.axaml:

&lt;Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:views="using:MultiPageApp.Views"
        xmlns:vm="using:MultiPageApp.ViewModels"&gt;
  &lt;Window.DataTemplates&gt;
    &lt;DataTemplate DataType="{x:Type vm:HomePageViewModel}"&gt;
      &lt;views:HomePageView /&gt;
    &lt;/DataTemplate&gt;
    &lt;DataTemplate DataType="{x:Type vm:SettingsPageViewModel}"&gt;
      &lt;views:SettingsPageView /&gt;
    &lt;/DataTemplate&gt;
  &lt;/Window.DataTemplates&gt;
 
  &lt;ContentControl Content="{Binding CurrentPage}" /&gt;
&lt;/Window&gt;

&lt;Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:views="using:MultiPageApp.Views" xmlns:vm="using:MultiPageApp.ViewModels"&gt; &lt;Window.DataTemplates&gt; &lt;DataTemplate DataType="{x:Type vm:HomePageViewModel}"&gt; &lt;views:HomePageView /&gt; &lt;/DataTemplate&gt; &lt;DataTemplate DataType="{x:Type vm:SettingsPageViewModel}"&gt; &lt;views:SettingsPageView /&gt; &lt;/DataTemplate&gt; &lt;/Window.DataTemplates&gt; &lt;ContentControl Content="{Binding CurrentPage}" /&gt; &lt;/Window&gt;

MainWindowViewModel:

public class MainWindowViewModel : ViewModelBase
{
    private ViewModelBase _currentPage;
 
    public ViewModelBase CurrentPage
    {
        get =&gt; _currentPage;
        set =&gt; this.RaiseAndSetIfChanged(ref _currentPage, value);
    }
 
    public MainWindowViewModel()
    {
        CurrentPage = new HomePageViewModel();
    }
 
    public void OpenSettings()
    {
        CurrentPage = new SettingsPageViewModel();
    }
}

public class MainWindowViewModel : ViewModelBase { private ViewModelBase _currentPage; public ViewModelBase CurrentPage { get =&gt; _currentPage; set =&gt; this.RaiseAndSetIfChanged(ref _currentPage, value); } public MainWindowViewModel() { CurrentPage = new HomePageViewModel(); } public void OpenSettings() { CurrentPage = new SettingsPageViewModel(); } }

Если используете ReactiveUI, команды лучше делать через ReactiveCommand. Если навигация большая, вынесите её в отдельный NavigationService, чтобы страницы не создавали друг друга напрямую. Тогда MainWindowViewModel будет только вызывать Navigate(new SettingsPageViewModel()), а не знать детали создания всех экранов.

Для кнопок навигации можно привязать команды в боковом меню или верхней панели. Важно, чтобы UserControl страницы не создавал MainWindow и не менял ContentControl напрямую — иначе MVVM быстро превратится в ручное управление окнами из code-behind.

Для нескольких страниц с историей можно хранить стек:

private readonly Stack&lt;ViewModelBase&gt; _history = new();
 
public void Navigate(ViewModelBase page)
{
    _history.Push(CurrentPage);
    CurrentPage = page;
}

private readonly Stack&lt;ViewModelBase&gt; _history = new(); public void Navigate(ViewModelBase page) { _history.Push(CurrentPage); CurrentPage = page; }

Итог: делайте навигацию через CurrentPage + ContentControl + DataTemplates. Это чистый MVVM-подход для Avalonia: ViewModel выбирает состояние, Avalonia сама подставляет нужный View.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно