我想了解更多关于MVVM在WPF中的实现,目前需要一些使用ViewModels进行导航的指导。我正在关注来自Rachel's blog的WPF导航示例,并需要从其他ViewModel调用ApplicationViewModel的Command。MVVM从另一个viewmodel调用WPF命令的方式是什么?
根据博客,从MainWindow切换视图非常清晰,但我想知道更多关于视图间导航,即说我有主窗口上的Home,Product和Contact按钮以及View和ViewModel类,现在我想要从主视图中的某个按钮而不是MainWindow打开联系人页面。我已经在Home ViewModel中编写了一些代码来实现,但是我怀疑这是否是MVVM的最佳实践。有没有什么办法可以从HomeView.XAML实现相同?
代码片段来自博客 - ApplicationViewModel.cs
private ICommand _changePageCommand;
private IPageViewModel _currentPageViewModel;
private List<IPageViewModel> _pageViewModels;
public ApplicationViewModel()
{
// Add available pages in c'tor
PageViewModels.Add(new HomeViewModel(this));
PageViewModels.Add(new ProductsViewModel());
PageViewModels.Add(new ContactViewModel());
}
public ICommand ChangePageCommand
{
get
{
if (_changePageCommand == null)
_changePageCommand = new RelayCommand(
p => ChangeViewModel((IPageViewModel)p), p => p is IPageViewModel);
return _changePageCommand;
}
}
private void ChangeViewModel(IPageViewModel viewModel)
{
if (!PageViewModels.Contains(viewModel))
PageViewModels.Add(viewModel);
CurrentPageViewModel = PageViewModels.FirstOrDefault(vm => vm == viewModel);
}
代码片段来自博客 - ApplicationView.xaml
<Window.Resources>
<DataTemplate DataType="{x:Type local:HomeViewModel}">
<local:HomeView />
</DataTemplate>
<!-- Data template for other views -->
</Window.Resources>
<DockPanel>
<Border DockPanel.Dock="Left" BorderBrush="Black" BorderThickness="0,0,1,0">
<ItemsControl ItemsSource="{Binding PageViewModels}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name}"
Command="{Binding DataContext.ChangePageCommand,
RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
CommandParameter="{Binding }"/>
<!--All closing tags-->
我里面HomeViewModel.cs代码
// This is the command to get bind with my button inside Home view to invoke Contact view
private ICommand _loadContactCommand;
public ICommand LoadContactCommand
{
get
{
if (_loadContactCommand == null)
_loadContactCommand = new RelayCommand(p => LoadOtherView());
return _loadContactCommand;
}
}
private void LoadOtherView()
{
// _appVM is the instance of 'ApplicationViewModel' which is being set from c'tor
// Even I'm thinking to pass Contact view member of ApplicationViewModel class here,
// as I need exactly the same instance of the Contact which has been created earlier
_appVM.ChangePageCommand.Execute(new ContactViewModel());
}
您可以使用调解模式。 –
@ rory.ap我了解调解器模式的基本原理。但是如何混合使用MVVM和Mediator? – Anup