Wpf 如何保持活跃的用户控制?

Wpf 如何保持活跃的用户控制?,wpf,mvvm,keep-alive,Wpf,Mvvm,Keep Alive,我有一个与包含用户控件的ContentControl一起工作的向导项目。 我通过主窗口中的XAML文件进行实例化: <DataTemplate DataType="{x:Type ViewModel:OpeningViewModel}"> <view:OpeningView/> </DataTemplate> <DataTemplate DataType="{x:Type ViewModel:SecondUCVie

我有一个与包含用户控件的ContentControl一起工作的向导项目。 我通过主窗口中的XAML文件进行实例化:

    <DataTemplate DataType="{x:Type ViewModel:OpeningViewModel}">
        <view:OpeningView/>
   </DataTemplate>

    <DataTemplate DataType="{x:Type ViewModel:SecondUCViewModel}">
        <view:SecondUCView/>
    </DataTemplate>
专用ICommand_NavigateNext命令; 公共ICommand NavigateNext命令 { 得到 { 如果(_NavigateNextCommand==null) { _NavigateNextCommand=new RelayCommand(参数=>this.MoveToNextPage(),参数=>CanMoveToNextPage); } 返回_NavigateNextCommand; } }

    private ICommand _NavigateBackCommand;
    public ICommand NavigateBackCommand
    {
        get
        {
            if (_NavigateBackCommand == null)
            {
                _NavigateBackCommand = new RelayCommand(param => this.MoveToPreviousPage(), param => CanMoveToPreviousPage);
            }
            return _NavigateBackCommand;
        }
    }



   private bool CanMoveToNextPage
    {
        get
        {
            return this.CurrentPage != null && this.CurrentPage.CanMoveNext;
        }
    }

    bool CanMoveToPreviousPage
    {
        get { return 0 < this.CurrentPageIndex && CurrentPage.CanMoveBack; }
    }

    private void MoveToNextPage()
    {
        if (this.CanMoveToNextPage)
        {
            if (CurrentPageIndex >= _pages.Count - 1)
                Cancel();
            if (this.CurrentPageIndex < _pages.Count - 1)
            {
                this.CurrentPage = _pages[this.CurrentPageIndex + 1];
            }
        }
    }

    void MoveToPreviousPage()
    {
        if (this.CanMoveToPreviousPage)
        {
            this.CurrentPage = _pages[this.CurrentPageIndex - 1];
        }
    }
private ICommand\u NavigateBackCommand;
公共ICommand NavigateBack命令
{
得到
{
如果(_NavigateBackCommand==null)
{
_NavigateBackCommand=new RelayCommand(参数=>this.MoveToPreviousPage(),参数=>CanMoveToPreviousPage);
}
返回_navigateback命令;
}
}
私有布尔可移动到下一页
{
得到
{
返回this.CurrentPage!=null&&this.CurrentPage.CanMoveNext;
}
}
布尔可以移动到上一页
{
获取{return 0=\u pages.Count-1)
取消();
if(this.CurrentPageIndex<_pages.Count-1)
{
this.CurrentPage=_pages[this.CurrentPageIndex+1];
}
}
}
void MoveToPreviousPage()
{
如果(此.CanMoveToPreviousPage)
{
this.CurrentPage=_pages[this.CurrentPageIndex-1];
}
}

而ContentControl包含绑定到CurrentPage的UC,您可以通过在XAML中硬编码用户控件而不是使用数据模板来实现这一点。DataTemplates将在每次实例化时创建新控件。但是,由于使用MVVM,还可以在对ViewModels的更改之间移动所有要持久化的数据,并确保ViewModel对象始终相同。然后,数据模板仍将创建新控件,但它们将包含与以前相同的信息。

我最近在MVVM中的视图中遇到了相同的问题。基本上,我想缓存需要一段时间才能渲染的视图。如果您熟悉ViewModelLocator,这种方法应该是直截了当的

在客户端(例如WPF)项目中,我创建了一个ViewLocator类,如下所示:

public class ViewLocator : ObservableObject
{
    #region Properties

    private View _myView;
    public View MyView
    {
        get { return _myView; }
        set { Set(() => MyView, ref _myView, value); }
    }

    #endregion Properties

    #region Constructors

    public ViewLocator()
    {
        RegisterViews();
    }

    #endregion Constructors

    #region Private Methods

    private void RegisterViews()
    {
        MyView = new View();
    }

    #endregion Private Methods
}
为了在数据模板中使用它,我将ViewLocator指定为一个静态应用程序资源,因此只实例化了一个实例——在我的例子中,我将它放在App.xaml中。要使用ViewLocator及其“视图”属性,我执行了以下操作:

<vl:ViewLocator x:Key="ViewLocator" />
<DataTemplate DataType="{x:Type vm:ViewModel}">
    <ContentControl Content="{Binding Source={StaticResource ViewLocator}, Path=MyView}" />
</DataTemplate>


通过这种方式,每个视图只实例化一次,并且可以重用。

如何在这两个UCs之间导航?你能发布代码吗?看我的主题,我在那里添加了代码。我认为用XAML硬编码更容易解决问题。你能说得更具体些吗?我对语法不太清楚。我在XAML和WPF方面非常出色。再次感谢阅读您的代码,我真的推荐第二种方法:只需将用户可以更改的所有内容放入ViewModels中,它就会自动持久化。如果您不想这样做,您可能最好将布局更改为对每个页面使用TabControl和TabItem,并对每个页面使用相应的UserControl进行硬编码。但是,这看起来会有所不同,您必须事先知道每个页面的ViewModel的类型。
<vl:ViewLocator x:Key="ViewLocator" />
<DataTemplate DataType="{x:Type vm:ViewModel}">
    <ContentControl Content="{Binding Source={StaticResource ViewLocator}, Path=MyView}" />
</DataTemplate>