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

如何在WPF MVVM explorer类应用程序中实现依赖于当前选择的菜单项,wpf,mvvm,relaycommand,Wpf,Mvvm,Relaycommand,我是WPF和MVVM的新手,我正在开发一个利用这两种技术的应用程序。该应用程序类似于Windows资源管理器,因此考虑一个应用程序,它带有一个带有菜单的主窗口(SHILVIEWVIEW模型)、一个树控件(TeeVIEWMeMod)和一个列表控件(ListVIEWTMIDE)。我想实现诸如Edit->Delete之类的菜单项,它删除当前选定的项(可能在树中或列表中) 我使用的是Josh Smith的RelayCommand,将menuitem绑定到ShellViewModel中的DeleteIte

我是WPF和MVVM的新手,我正在开发一个利用这两种技术的应用程序。该应用程序类似于Windows资源管理器,因此考虑一个应用程序,它带有一个带有菜单的主窗口(SHILVIEWVIEW模型)、一个树控件(TeeVIEWMeMod)和一个列表控件(ListVIEWTMIDE)。我想实现诸如Edit->Delete之类的菜单项,它删除当前选定的项(可能在树中或列表中)

我使用的是Josh Smith的RelayCommand,将menuitem绑定到ShellViewModel中的DeleteItem命令很容易。然而,实现deleteItem命令似乎需要ShellViewModel和两个子视图模型(TreeViewModel和ListViewModel)之间有相当紧密的耦合,以跟踪焦点/选择,并将操作定向到适当的子视图模型进行实现。这对我来说似乎是错的,让我觉得我错过了什么

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

我不确定的是如何将命令从ShellViewModel向下路由到ListViewModel或TreeViewModel,以便在不弄乱代码的情况下执行实际工作。总有一天,该应用程序将扩展到包括两个以上的孩子,我希望shell尽可能不了解孩子,使扩展尽可能无痛

查看一些示例WPF/MVVM应用程序(Karl Shifflett的密文等),我还没有看到任何代码能够做到这一点(或者我不理解它)


不管你认为我的方法有多么离谱,或者我只是错过了一个细微的差别,请分享你的想法,帮助我回到正轨。谢谢

Josh Smith的MVVM实现存在一些固有的问题。看看沃德·贝尔关于这个主题的帖子:。您可能想看看其他一些MVVM框架,例如Caliburn,它们采用ViewModel优先的方法并打破这种耦合。

Josh Smith的MVVM实现存在一些固有的问题。看看沃德·贝尔关于这个主题的帖子:。您可能希望了解一些替代MVVM框架,例如Caliburn,它们采用ViewModel优先的方法并打破这种耦合。

RelayCommand只是在ViewModel中获取可绑定到视图的命令的一种方式

我想我倾向于从所有不同的MVVM架构变体和示例应用中退一步,只使用好的旧OOD。为什么不为TreeViewVm和ListViewVm创建某种类型的ViewModel基类(即DetailsViewModelBase)。将DeleteCommand与CanDelete和Delete方法放在一起,这些方法的实现与子类共享的实现一样多(如果没有,则放在abstract中),还可以放一个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}"
                      >

正在选择的键绑定EdItem和IsSynchronizedWithCurrentItem

HTH,

Berryl

RelayCommand只是在ViewModel中获取可绑定到视图的命令的一种方式

我想我倾向于从所有不同的MVVM架构变体和示例应用中退一步,只使用好的旧OOD。为什么不为TreeViewVm和ListViewVm创建某种类型的ViewModel基类(即DetailsViewModelBase)。将DeleteCommand与CanDelete和Delete方法放在一起,这些方法的实现与子类共享的实现一样多(如果没有,则放在abstract中),还可以放一个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}"
                      >

正在选择的键绑定EdItem和IsSynchronizedWithCurrentItem

HTH,

Berryl

我找到了Kent Boogaart写的一篇文章,描述了他所谓的ActiveAwareCommand。这似乎符合我的要求,尽管我还没有尝试过。帖子上的一条评论提到Prism的IActiveAware具有类似的行为。

我发现Kent Boogaart的一篇文章描述了他所谓的ActiveAwareCommand。这似乎符合我的要求,尽管我还没有尝试过。帖子上的一条评论提到Prism的IActiveAware也有类似的行为。

感谢您链接到Ward Bell的帖子。我不能百分之百确定它如何适用于我的问题。您是指引用事件聚合作为我的问题的可能解决方案吗?是的,您应该使用事件聚合作为不同ViewModel之间通信的手段。他们之间不应该有硬的参照物。MVVM体系结构概述的另一个很好的参考是Rob Eisenberg的Build your Own MVVM from Mix 10(),感谢您链接到Ward Bell的帖子。我不能百分之百确定它如何适用于我的问题。您是指引用事件聚合作为我的问题的可能解决方案吗?是的,您应该使用事件聚合作为不同ViewModel之间通信的手段。他们之间不应该有硬的参照物。MVVM架构概述的另一个很好的参考是Rob Eisenberg的Build your Own MVVM from Mix 10()