如何保持用户控制?

时间:2012-09-28 20:15:39

标签: wpf mvvm keep-alive

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

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

    <DataTemplate DataType="{x:Type ViewModel:SecondUCViewModel}">
        <view:SecondUCView/>
    </DataTemplate>

但是当我在UC之间导航时,UC似乎不像“保持活力”那样,每个UC切换都会创建新的实例。我怎么能避免呢? 我想为每个UC创建一个实例,并且只在不创建新实例的情况下在这些实例之间导航。

我知道如何编写单例,但我的项目基于MVVM而且我是WPF的新手,所以我不确定最好的方法是什么。

感谢

更新

这里是viewModel的代码:

在viewModel中我有:

private ObservableCollection _pages = null;         私有NavigationBaseViewModel _currentPage;

    #endregion

    #region Properties

    public int CurrentPageIndex
    {
        get
        {
            if (this.CurrentPage == null)
            {
                return 0;
            }
            return _pages.IndexOf(this.CurrentPage);
        }
    }

    public NavigationBaseViewModel CurrentPage
    {
        get { return _currentPage; }

        private set
        {
            if (value == _currentPage)
                return;

            _currentPage = value;
            OnPropertyChanged("CurrentPage");
        }
    }

私人ICommand _NavigateNextCommand;         公共ICommand NavigateNextCommand         {             得到             {                 if(_NavigateNextCommand == null)                 {                     _NavigateNextCommand = new RelayCommand(param =&gt; this.MoveToNextPage(),param =&gt; CanMoveToNextPage);                 }                 return _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];
        }
    }

包含UC的ContentControl绑定到CurrentPage

2 个答案:

答案 0 :(得分:1)

您可以通过在XAML中硬编码UserControl而不是使用DataTemplates来实现。 DataTemplates将在每次实例化时创建新控件。但是,由于您使用MVVM,您还可以将所需的所有数据移动到ViewModel的更改之间,并确保ViewModel对象始终相同。然后,DataTemplates仍然会创建新控件,但它们将包含与以前相同的信息。

答案 1 :(得分:0)

我最近遇到了与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,请查看&#34;查看&#34;属性,我做了以下:

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

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