6

我有与包含用户控件的 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 我有:

私有 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 { get { if (_NavigateNextCommand == null) { _NavigateNextCommand = new RelayCommand(param => this.MoveToNextPage(), param => 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];
        }
    }

以及包含绑定到 CurrentPage 的 UC 的 ContentControl

4

2 回答 2

1

You can do that by hardcoding the UserControls in XAML, instead of using DataTemplates. DataTemplates will create new Controls every time they are instantiated. However, since you use MVVM, you could also move all data you want persisted between the changes to the ViewModels, and make sure that the ViewModel objects are always the same. Then, the DataTemplates would still create new controls, but they would contain the same information as before.

于 2012-09-29T10:01:50.277 回答
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 及其“视图”属性,我执行了以下操作:

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

通过这样做,每个视图只被实例化一次并且可以被重用。

于 2014-11-04T11:09:58.777 回答