【发布时间】:2012-02-07 03:33:15
【问题描述】:
我有一个 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 应该使用 DataTemplates 呈现每个 WorkspaceViewModel 的视图。
<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 或 TreeViews,它们的内部状态就会丢失。例如,如果我有一个带有可展开和可排序行的 DataGrid,当用户导航到下一个屏幕然后返回 DataGrid 屏幕时,展开/折叠状态和排序顺序就会丢失。在大多数情况下,可以跟踪需要在导航之间保留的每条状态信息,但这似乎是一种非常不雅的方法。
有没有更好的方法在更改整个屏幕的导航事件之间保留视图的整个状态?
【问题讨论】:
标签: wpf mvvm navigation datatemplate