MVVM を使用して開発された、比較的単純な階層データ マスター/詳細 WPF ウィンドウがあります。ここで、ウィンドウは、詳細ビューの ViewModel をプロパティの 1 つとして公開する 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
Roslyn を使用して Visual Basic に移植したJosh Smith のVMCommandingコードの実装が含まれています。
Window の XAML は基本的に次のようになりますが、無関係な詳細と多数の閉じ括弧が省略されています。
「Master」のアイテムを選択すると、「Detail」の が対応する DetailViewModel に設定されますListBox
。そのリスト ボックスで 2 番目の項目を選択すると、[詳細] ボックスの が、選択した対応する DetailViewModel に変更されます。パフォーマンス上の理由から、一度選択すると DetailViewModel が保持され、[詳細] ボックスの内外に切り替えられます。DataContext
ListBox
DataContext
DataContext
「詳細」でアイテムを選択するListBox
と、「マスター」ボックスで選択された ViewModel によってキャッチされることになっている RoutedCommand がトリガーされます。ただし、RoutedCommand
がフォーカスを正しい DetailViewModel に変更することはありません。コマンドは、最初の「マスター」ListBox 選択に対応する 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>