Как сохранить полное состояние представления при переходе между представлениями в приложении MVVM?

У меня есть приложение MVVM, которое требует базовой навигации между экранами вперед / назад. В настоящее время я реализовал это с помощью WorkspaceHostViewModel, который отслеживает текущую рабочую область и предоставляет необходимые команды навигации следующим образом.

public class WorkspaceHostViewModel : ViewModelBase
{
    private WorkspaceViewModel _currentWorkspace;
    public WorkspaceViewModel CurrentWorkspace
    {
        get { return this._currentWorkspace; }
        set
        {
            if (this._currentWorkspace == null
                || !this._currentWorkspace.Equals(value))
            {
                this._currentWorkspace = value;
                this.OnPropertyChanged(() => this.CurrentWorkspace);
            }
        }
    }

    private LinkedList<WorkspaceViewModel> _navigationHistory;

    public ICommand NavigateBackwardCommand { get; set; }
    public ICommand NavigateForwardCommand { get; set; }
}

У меня также есть WorkspaceHostView, который привязывается к WorkspaceHostViewModel следующим образом.

<Window x:Class="MyNavigator.WorkspaceHostViewModel"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Window.Resources>
    <ResourceDictionary Source="../../Resources/WorkspaceHostResources.xaml" />
  </Window.Resources>

  <Grid>
    <!-- Current Workspace -->
    <ContentControl Content="{Binding Path=CurrentWorkspace}"/>
  </Grid>

</Window>

В файле WorkspaceHostResources.xaml я связываю представление, которое WPF должен использовать для рендеринга каждой WorkspaceViewModel с помощью DataTemplates.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:MyNavigator">

  <DataTemplate DataType="{x:Type local:WorkspaceViewModel1}">
    <local:WorkspaceView1/>
  </DataTemplate>

  <DataTemplate DataType="{x:Type local:WorkspaceViewModel2}">
    <local:WorkspaceView2/>
  </DataTemplate>

</ResourceDictionary>

Это работает довольно хорошо, но одним из недостатков является то, что представления воссоздаются между каждой навигацией из-за механизма DataTemplates. Если представление содержит сложные элементы управления, такие как DataGrids или TreeView, их внутреннее состояние теряется. Например, если у меня есть DataGrid с расширяемыми и сортируемыми строками, состояние развертывания / свертывания и порядок сортировки теряются, когда пользователь переходит на следующий экран, а затем обратно на экран DataGrid. В большинстве случаев можно было бы отслеживать каждую часть информации о состоянии, которую необходимо сохранять между переходами, но это кажется очень неэлегантным подходом.

Есть ли лучший способ сохранить полное состояние представления между событиями навигации, которые изменяют весь экран?

12
задан Dan J 10 January 2012 в 18:31
поделиться