首页 文章

WPF数据绑定ContextMenuItem 's CommandParameter to TreeViewItem' s DataContext

提问于
浏览
0

我在TreeViewItem上使用Command模式(以及其他内容)上下文菜单,它使用HierarchicalDataTemplates . MainWindowViewModel(Window的静态资源)具有公开单个对象的属性,而单个对象又具有表示命令的属性 . 我能够很好地执行命令,但是有些命令需要将TreeViewItem的DataContext作为CommandParameter传递 .

下面是一个具体示例:树的一个节点将ItemsSource绑定到各个AnalysisMain对象的ObservableCollection . 每个生成的子节点都有一个ContextMenu(带有绑定到AnalysisController的DataContext),其中包含一个Remove MenuItem(以及其他) . Remove MenuItem的Command属性绑定到AnalysisController单例对象上的CommandRemove命令(它执行得很好) . 但是这也需要将CommandParameter绑定到AnalysisMain对象,该对象充当树中子节点的DataContext . 我尝试使用RelativeSource,将AncestorType设置为TreeViewItem,将Path设置为DataContext:

<HierarchicalDataTemplate DataType="{x:Type vmAnalysis:AnalysisMain}">
    <WrapPanel Orientation="Horizontal">
        <Image Source="Analysis\Icon_Analysis_Main_16_Normal.png" Margin="0,0,2,0" Width="16"/>
        <TextBlock Text="{Binding TreeViewTitle}">
            <TextBlock.ContextMenu>
                <ContextMenu DataContext="{StaticResource mainWindowViewModel}">
                    <MenuItem Header="Remove" Command="{Binding Path=AnalysisController.CommandRemove}"
                              CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}, AncestorLevel=4}, Path=DataContext}">
                    </MenuItem>
                </ContextMenu>
            </TextBlock.ContextMenu>
        </TextBlock>
    </WrapPanel>
</HierarchicalDataTemplate>

如果没有AncestorLevel设置,当我打开ContextMenu时,我会在Output窗口中看到以下内容:

System.Windows.Data错误:4:无法找到绑定源,引用'RelativeSource FindAncestor,AncestorType ='System.Windows.Controls.TreeViewItem',AncestorLevel ='4'' . BindingExpression:路径= DataContext的;的DataItem = NULL; target元素是'MenuItem'(Name =''); target属性是'CommandParameter'(类型'Object')

我为AncestorLevel尝试了几个值无济于事 .

通过检查Christian Mosers WPF Inspector中的Visual Tree,我没有在可视化树中看到上下文菜单 . 虽然TreeViewItem显示DataContext对象 . 我只需要一种“导航”它的方式来绑定它 .


作为替代方案,我尝试单独保留ContextMenu DataContext并将Command Binding的Source设置为指向AnalysisController . 这也适用于执行命令,但我无法绑定到CommandParameter的TreeViewItem的DataContext:

<ContextMenu>
    <MenuItem Header="Remove" Command="{Binding Source={StaticResource mainWindowViewModel}, Path=AnalysisController.CommandRemove}"
              CommandParameter="{Binding Source={RelativeSource Self}, Path=DataContext}">
    </MenuItem>
</ContextMenu>

我也试过使用CommandParameter =“”,这也行不通 . (在这两种情况下,我只是将null作为参数发送 . 没有警告/错误被写入输出窗口 . )编辑:对于有此问题的其他人,第二个选项从一开始就注定失败,因为我错误地输入了Source = ,它将引用MenuItem而不是TreeViewItem . 但是,使用AncestorType / AncestorLevel更改它没有任何区别 .

1 回答

  • 1

    你必须使用 ContextMenuPlacementTarget 属性

    <Setter Property="ContextMenu">
            <Setter.Value>
                <ContextMenu
            DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
                </ContextMenu>
            </Setter.Value>
     </Setter>
    

    并在你 MenuItemRelativeSourceContextMenu 然后使用 PlacementTarget.DataContext 作为你的 CommandParameter 绑定

相关问题