Как реализовать навигацию WPF страничную, с сохранением контекста?

Для реализации страничной навигации WPF с сохранением контекста вы можете использовать фрейм (Frame) и его навигационное свойство (NavigationService).

Первым шагом создайте главное окно вашего приложения. В XAML-разметке окна добавьте элемент Frame, который будет использоваться для отображения различных страниц. Примерно так:

<Window x:Class="YourAppName.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Your App Name" Height="450" Width="800">
    <Grid>
        <Frame x:Name="pageFrame" NavigationUIVisibility="Hidden" />
    </Grid>
</Window>

Далее в коде вашего окна создайте методы для навигации по страницам. Например:

public void NavigateToPage1()
{
    Page1 page1 = new Page1();
    pageFrame.Content = page1;
}

public void NavigateToPage2()
{
    Page2 page2 = new Page2();
    pageFrame.Content = page2;
}

В этих методах вы создаете экземпляры ваших страниц (Page) и устанавливаете контент фрейма равным этим страницам. При этом фрейм автоматически отобразит указанные страницы на UI.

Теперь вы можете вызывать эти методы по вашему выбору, например, при нажатии на кнопки в вашем главном окне.

Однако, для сохранения контекста на каждой странице, вам необходимо управлять состоянием страниц и отслеживать, какие страницы были уже просмотрены. Для этого вы можете создать класс-менеджер навигации, который будет отслеживать и хранить последовательность посещенных страниц и их состояние. После возврата к странице, вы можете восстановить предыдущее состояние.

Пример класса-менеджера навигации:

public class NavigationManager
{
    private Stack<Page> _pageStack;

    public NavigationManager()
    {
        _pageStack = new Stack<Page>();
    }

    public void NavigateTo(Page page)
    {
        _pageStack.Push(page);
        pageFrame.Content = page;
    }

    public void NavigateBack()
    {
        _pageStack.Pop();
        Page previousPage = _pageStack.Peek();
        pageFrame.Content = previousPage;
    }
}

Пример использования:

private NavigationManager _navigationManager;

public MainWindow()
{
    InitializeComponent();
    _navigationManager = new NavigationManager();
}

private void Button1_Click(object sender, RoutedEventArgs e)
{
    Page1 page1 = new Page1();
    _navigationManager.NavigateTo(page1);
}

private void Button2_Click(object sender, RoutedEventArgs e)
{
    Page2 page2 = new Page2();
    _navigationManager.NavigateTo(page2);
}

private void BackButton_Click(object sender, RoutedEventArgs e)
{
    _navigationManager.NavigateBack();
}

Теперь, при каждом вызове метода NavigateTo(), вы сохраняете текущую страницу в стеке, а при нажатии на кнопку "назад" вызываете метод NavigateBack(), который восстанавливает предыдущую страницу из стека и устанавливает ее контент как текущую страницу фрейма.

Таким образом, у вас будет производиться навигация между страницами, с сохранением контекста на каждой странице.