我想编写一个显示不同页面/场景的WPF应用程序。因此,我有一个ViewModel(MainViewModel),它提供了场景列表(SceneViewModel)。每个场景都有一个名称,可以通过属性SceneName
进行访问。
我在Window.DataContext中创建MainViewModel:
<Window.DataContext>
<!-- Declaratively create an instance of the main model -->
<models:MainViewModel />
</Window.DataContext>
然后,我想要一个列出所有场景的菜单项。单击其中一个菜单项时,场景应发生变化。因此,我在MainViewMode中创建了一个Command:ChangeSceneCommand。
在XAML中,我想通过以下方式创建菜单列表:
<Menu Grid.Row="0">
<Menu.Resources>
<Style x:Key="SetSceneCommandItem" TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding SceneName}"/>
<Setter Property="Command" Value="{Binding SetSceneCommand}"/> <-- Here is the problem
<Setter Property="IsChecked" Value="False" />
</Style>
</Menu.Resources>
<MenuItem Header="Scenes" ItemsSource="{Binding Scenes}" <-- Scenes is a list with scenes^^
ItemContainerStyle="{StaticResource SetSceneCommandItem}" /> <-- Here the style is set
</Menu>
Item-Header绑定(bind)得很好,但是找不到“SetSceneCommand”,因为wpf试图在SceneViewModel中找到“SetSceneCommand”属性。我如何说WPF在样式之外的数据上下文中访问模型?
PS:您可能已经注意到SetSceneCommand将需要一个场景作为参数才能工作,但我想稍后实现。
最佳答案
您可以使用 RelativeSource
。如果SetSceneCommand
是Menu
使用的同一上下文的一部分,那么它将看起来像这样:
<Setter
Property="Command"
Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type Menu}}, Path=DataContext.SetSceneCommand}"/>
这告诉
Binding
在视觉树上,直到Menu
并从那里获取DataContext.SetSceneCommand