我是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等),我还没有看到任何代码执行此操作(或者我不理解它)。
无论你认为我的方法是偏离基础,还是我只是错过了一个小细微差别,请分享你的想法并帮助我重回正轨。谢谢!
答案 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具有相似的行为。