如何在WPF MVVM类似浏览器的应用程序中实现依赖于当前选择的菜单项

时间:2010-03-26 18:30:24

标签: wpf mvvm relaycommand

我是WPF和MVVM的新手,我正在开发一个使用两者的应用程序。该应用程序类似于Windows资源管理器,因此请考虑具有带有菜单(ShellViewModel)的主窗口,树控件(TreeViewModel)和列表控件(ListViewModel)的应用程序。我想实现菜单项,如编辑 - >删除,删除当前所选项目(可能在树中或列表中)。

我正在使用Josh Smith的RelayCommand,并且将menuitem绑定到ShellViewModel中的DeleteItemCommand很容易。看起来像实现DeleteItemCommand,需要在ShellViewModel和两个子视图模型(TreeViewModel和ListViewModel)之间进行一些相当紧密的耦合,以跟踪焦点/选择并将操作指向适当的子实现。这对我来说似乎不对,让我觉得我错过了什么。

编写焦点管理器和/或选择管理器来进行簿记似乎并不太难,并且可以在不将类耦合在一起的情况下完成。窗口系统已经跟踪哪个视图具有焦点,似乎我正在复制代码。

我不确定的是我如何将命令从ShellViewModel路由到ListViewModel或TreeViewModel来进行实际工作而不会弄乱代码。有一天,申请将扩展到包括两个以上的孩子,我希望shell尽可能地不让孩子们尽可能无痛地扩展。

查看一些示例WPF / MVVM应用程序(Karl Shifflett的CipherText,Josh Smith's MVVM Demo等),我还没有看到任何代码执行此操作(或者我不理解它)。

无论你认为我的方法是偏离基础,还是我只是错过了一个小细微差别,请分享你的想法并帮助我重回正轨。谢谢!

3 个答案:

答案 0 :(得分:1)

Josh Smith实施MVVM存在一些固有问题。看看Ward Bell关于这个主题的帖子:http://neverindoubtnet.blogspot.com/2010/03/mvvm-josh-smiths-way.html。您可能需要查看一些替代MVVM框架,例如Caliburn,它采用ViewModel第一种方法并打破这种耦合。

答案 1 :(得分:0)

RelayCommand只是一种在ViewModel中获取可以绑定到View的命令的方法。

我想我会倾向于退出所有不同的MVVM架构变体和示例应用程序,并且只使用好的旧OOD。为什么没有TreeViewVm和ListViewVm的某种ViewModel基类(即DetailsViewModelBase)。使用CanDelete和Delete方法在其中放置一个DeleteCommand,这些方法具有与子类共享一样多的实现(或者如果没有那么抽象),以及一个SelectedItem。然后将SelectedItem绑定到类似于下面的xaml的控件:

    <ListView AlternationCount="2" MinHeight="250" MaxHeight="400" 
          ItemsSource="{Binding Projects.View}" 
          IsSynchronizedWithCurrentItem="True"
          SelectedItem="{Binding SelectedProject, Mode=TwoWay}"
          behaviors:SelectionBehavior.DoubleClickCommand="{Binding PickCommand}"
          ItemContainerStyle="{StaticResource listingRowStyle}"
                      >

键绑定是SelectedItem和IsSynchronizedWithCurrentItem。

HTH,
Berryl

答案 2 :(得分:0)

我找到了Kent Boogaart的一个blog post来描述他所谓的ActiveAwareCommand。这似乎做了我想要的,虽然我还没有尝试过。对帖子的评论提到Prism的IActiveAware具有相似的行为。