【发布时间】:2017-06-29 15:17:37
【问题描述】:
我正在尝试详细了解 WPF 中的 MVVM 实现,目前需要一些有关使用 ViewModel 进行导航的指导。我正在关注来自Rachel's blog 的 WPF 导航示例,并且需要一种从其他 ViewModel 调用 ApplicationViewModel 命令的方法。
根据博客,从 MainWindow 切换视图非常清楚,但我想了解更多关于视图间导航的信息,即说我在 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?