У меня есть приложение 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. В большинстве случаев можно было бы отслеживать каждую часть информации о состоянии, которую необходимо сохранять между переходами, но это кажется очень неэлегантным подходом.
Есть ли лучший способ сохранить полное состояние представления между событиями навигации, которые изменяют весь экран?