WPF 切换视图

WPF switching views

我正在实现一个 WPF 应用程序,并且在单击按钮时切换视图模型。我必须通过 youtube 教程来实现导航商店。当我单击一个按钮时,navigateCommand 将执行,创建一个新的 viewModel 并通知视图发生变化。但是我不明白 OnCurrentViewModelChanged() 方法在做什么以及为什么需要它,操作 CurrentViewModelChanged 返回 void,并且是空的?或者我错过了什么? CurrentViewModelChanged 在做什么?有人可以解释一下吗?

public class NavigationStore
    {
        public event Action CurrentViewModelChanged;

        private NotifyPropertyChanged currentViewModel;
        public NotifyPropertyChanged CurrentViewModel
        {
            get => currentViewModel;
            set
            {
                currentViewModel = value;
                OnCurrentViewModelChanged();
            }
        }

        private void OnCurrentViewModelChanged()
        {
            CurrentViewModelChanged?.Invoke();
        }
    }
public class NavigateCommand<TViewModel> : CommandBase where TViewModel : NotifyPropertyChanged
    {
        private readonly NavigationStore _navigationStore;
        private readonly Func<TViewModel> _createViewModel;

        public NavigateCommand(NavigationStore navigationStore, Func<TViewModel> createViewModel)
        {
            _navigationStore = navigationStore;
            _createViewModel = createViewModel;
        }

        public override void Execute()
        {
            _navigationStore.CurrentViewModel = _createViewModel();
        }
    }
public class MainViewModel : NotifyPropertyChanged
    {
        private readonly NavigationStore _navigationStore;

        public NotifyPropertyChanged CurrentViewModel => _navigationStore.CurrentViewModel;

        public MainViewModel(NavigationStore navigationStore)
        {
            _navigationStore = navigationStore;

            _navigationStore.CurrentViewModelChanged += OnCurrentViewModelChanged;
        }

        private void OnCurrentViewModelChanged()
        {
            OnPropertyChanged(nameof(CurrentViewModel));
        }
    }

所以首先,我也遵循了他的教程(很可能是 SingletonSean 的)并且我不同意@BenicCode 对此的看法(虽然我不像他那样是 WPF 的专业人士),我真的喜欢他对问题的解释和解决方案。此外,他在整个指南中不断更改项目,实施更好的解决方案并解释为什么使用这个比那个更好。

OnCurrentViewModelChanged() 方法引发一个事件,以便调用订阅它的任何方法。然而,你其实并不需要它,你可以这样实现 NavigationStore:

NavigationStore.cs

public class NavigationStore : INavigationStore
    {
        private ViewModelBase? _currentViewModel;
        public ViewModelBase? CurrentViewModel
        {
            get => _currentViewModel;
            set
            {
                _currentViewModel?.Dispose();

                _currentViewModel = value;
                NavigationStateChanged?.Invoke();
            }
        }

        public event Action? NavigationStateChanged;
    }

现在,在您的 MainViewModel 中,您只需将 NavigationStateChanged 操作订阅到 OnCurrentViewModelChanged(),而不是在您的导航存储中再添加一种方法。

MainViewModel.cs

public class MainViewModel : ViewModelBase
    {
        private readonly INavigationStore _navigationStore;

        public ViewModelBase? CurrentViewModel => _navigationStore.CurrentViewModel;

        public MainViewModel(INavigationStore navigationStore)
        {
            _navigationStore = navigationStore;

            _navigationStore.NavigationStateChanged += OnNavigator_NavigationStateChanged;
        }

        private void OnNavigator_NavigationStateChanged()
        {
            OnPropertyChanged(nameof(CurrentViewModel));
        }
}

基本相同,只是简单了一点(不对请指正)。通过将 NavigationStateChanged 订阅到 OnNavigator_NavigationStateChanged,每当 NavigationStateChanged 被触发时,OnNavigator_NavigationStateChanged 也会触发,这将通知您的 UI 进行更改(因为您将 ContentControl 的 Content 属性 绑定到 CurrentViewModel 属性).

MainWindow.xaml

<Grid>
   <ContentControl Content="{Binding CurrentViewModel}" />
</Grid>

在本教程的这一点上,他只想演示真正基本的导航。随着您的进一步发展,事情会变得更加清晰和复杂。我真的建议完成他的教程,可能会有更好的指南,但作为起点,我找不到更好的渠道。