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