WPF上下文菜单,其项目被定义为数据模板(WPF context menu whose items

2019-09-18 05:04发布

我有一个显示的项目集合的列表视图中,每个项目都有它的底层数据视图模型(MVVM)。

我想这样做是显示上下文菜单中的不同菜单项,当用户用鼠标右击这些列表视图的项目之一。 显示的菜单项是取决于所选(即,底层视图模型的类型)的项的类型。

我希望下面的工作,但它并没有(没有项目显示在上下文菜单)。

<ListView.ContextMenu>
<ContextMenu DataContext="{Binding Path=PlacementTarget.SelectedItem, RelativeSource={RelativeSource Self}}">
    <ContextMenu.Resources>                        
        <DataTemplate DataType="{x:Type ViewModels:ViewModel1}">
            <MenuItem Header="DoStuffForVM1" Command="{Binding DoStuffForVM1Command}"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type ViewModels:ViewModel2}">
            <MenuItem Header="DoStuffForVM2" Command="{Binding DoStuffForVM2Command}"/>
        </DataTemplate>
    </ContextMenu.Resources>
    <ContentPresenter ContentSource="{Binding}" />
</ContextMenu>
</ListView.ContextMenu>

有任何想法吗?

谢谢。

Answer 1:

这对我的作品:

<ListView.ContextMenu>
<ContextMenu>
 <ContentPresenter Content="{Binding Path=PlacementTarget.SelectedItem, 
                             RelativeSource={RelativeSource AncestorType=ContextMenu}}" >
    <ContentPresenter.Resources>                        
        <DataTemplate DataType="{x:Type ViewModels:ViewModel1}">
            <MenuItem Header="DoStuffForVM1" Command="{Binding DoStuffForVM1Command}"/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type ViewModels:ViewModel2}">
            <MenuItem Header="DoStuffForVM2" Command="{Binding DoStuffForVM2Command}"/>
        </DataTemplate>
    </ContentPresenter.Resources>
  </ContentPresenter>
</ContextMenu>
</ListView.ContextMenu>


Answer 2:

这是因为你设置的ListView的文本菜单,让你的DataContext是ListView控件的外部背景下,而不是一个单独的列表项的视图模型。

您需要设置每个项目的文本菜单代替。 例如,使用样式:

<ListView.Resources>
    <ContextMenu x:Key="ItemContextMenu">
      <MenuItem Header="DoStuffForVM1" Command="{Binding DataContext.DoStuffForVM1Command, RelativeSource={RelativeSource AncestorType={x:Type ListView}}"/>
    </ContextMenu>
</ListView.Resources>
<ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}">
      <Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}"/>
    </Style>
</ListView.ItemContainerStyle>

然而,上述没有考虑不同类型的菜单。

如果要定义你的列表视图为每种类型的数据模板,最简单的方法是定义ContextMenu中的每个明确DataTemplate

如果没有,你必须与在样式触发器来做到这一点。 你可能有写一个转换器能够触发对象类型。



文章来源: WPF context menu whose items are defined as data templates