我有一个相对简单的分层数据主从 WPF 窗口,使用 MVVM 开发,其中 Window 指向一个 ViewModel,该 ViewModel 将 ViewModel 作为其属性之一公开用于详细视图:
Public Class MasterViewModel
Inherits ViewModelBase ' Contains an implementation of CommandSink
Private WithEvents _ViewerSelection As DetailViewModel
Public Property ViewerSelection As DetailViewModel
Set(value As DetailViewModel)
_ViewerSelection = value
RaisePropertyChanged("ViewerSelection")
End Set
Get
Return _ViewerSelection
End Get
End Property
ViewModelBase
包含 Josh Smith 的VMCommanding代码的实现,我使用 Roslyn 的东西将其移植到 Visual Basic。
Window 的 XAML 看起来基本上是这样的,其中包含不相关的细节和很多右括号被省略。
在“Master”中选择一个项目ListBox
会将DataContext
“Detail”ListBox
设置为相应的 DetailViewModel。在该列表框中选择第二个项目会将DataContext
“详细信息”框更改为所选内容的相应 DetailViewModel。出于性能原因,一旦选择,DetailViewModel 将被保留并在DataContext
“详细信息”框中切换进出。
在“详细信息”中选择一个项目ListBox
会触发一个 RoutedCommand,它应该被“主”框中选择的 ViewModel 捕获。但是,RoutedCommand
s 永远不会将焦点转移到正确的 DetailViewModel;该命令始终被与第一个“主”列表框选择相对应的 DetailViewModel 捕获。
我需要做些什么不同的事情?
<dx:DXWindow
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:local="clr-namespace:MyProject"
Title="{Binding ProjectTitle}"
local:CommandSinkBinding.CommandSink="{Binding}">
<dx:DXWindow.Resources>
<local:MasterViewModel x:Key="MViewM"/>
</dx:DXWindow.Resources>
<dx:DXWindow.DataContext>
<Binding Source="{StaticResource MViewM}" />
</dx:DXWindow.DataContext>
<Grid>
<ListBox ItemsSource="{Binding MasterListBox}">
<-- Selecting an item in the top list box causes a change to the DataContext
<ListBox ItemTemplate="{StaticResource MaterialDataTemplate}"
Name="DetailListBox"
DataContext="{Binding ViewerSelection}"
ItemsSource="{Binding Materials}"
local:CommandSinkBinding.CommandSink="{Binding}"
SelectionMode="Multiple">
<ListBox.CommandBindings>
<local:CommandSinkBinding Command="local:DetailVM.Filter"/>
</ListBox.CommandBindings>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="local:DetailVM.Filter" CommandParameter="{Binding ElementName=DetailListBox, Path=SelectedItems}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>