WPF中ContextMenu中的CommandParameters

时间:2009-02-02 19:29:22

标签: c# wpf .net-3.5

我有一个场景,我有一个WPF TreeView控件,其项目有HierarchicalDataTemplate。现在在HierarchicalDataTemplate内,我有一个Label,而Label有一个ContextMenu,其中包含Delete的菜单项。删除菜单项绑定到名为DeleteCommand的命令,该命令是已设置为DataType的{​​{1}}的类的一部分。

现在,我想在ContextMenu的HierarchicalDataTemplate菜单项TreeView的{​​{1}}中传递CommandParameters控件,以便我可以在删除时处理TreeViewItems的选择当前所选项目。

但是,如果我将Delete绑定为DeleteCommand或其他任何内容,除非绑定元素是CommandParameters中的属性,否则它始终为null。

任何人都可以帮我解决问题因为我认为,我已经尝试了所有可能的东西,比如RelativeSource和AncestorType等,但它总是为空。对我来说,它看起来像是框架中的限制或错误。

5 个答案:

答案 0 :(得分:17)

问题是ContextMenu是它自己的可视树的根,所以任何RelativeSource.FindAncestor绑定都不会超过ContextMenu。

一种解决方案是使用PlacementTarget属性从Label设置两阶段绑定:

<Label Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={
    x:Type TreeView}}}">
    <Label.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Delete" Command="{x:Static local:Commands.DeleteCommand}"
                CommandParameter="{Binding PlacementTarget.Tag, RelativeSource={
                RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"/>
        </ContextMenu>
    </Label.ContextMenu>
</Label>
然而,这非常hacky。最好将MenuItem的CommandTarget属性设置为ContextMenu的PlacementTarget,并在TreeView上设置命令处理程序。这意味着您不必传递TreeView。

答案 1 :(得分:1)

<ContextMenu>
    <MenuItem Header="Edit Item"
                   Command="{Binding EditItemCommand, Mode=OneWay}"
                   CommandParameter="{Binding Path=UIElement.(views:DataGridView.SelectedItems), RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" />
<ContextMenu>

答案 2 :(得分:0)

<MenuItem Header="..." 
          Command="{Binding Path=...}" 
          CommandParameter="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type ContextMenu}}}">
</MenuItem>

ContextMenu.PlacementTarget是Label,其中托管了menuitem。从Lavel,它的父Treeview是可访问的。

答案 3 :(得分:0)

对于 DataGrid 中的每个元素

<ContextMenu>
    <MenuItem Header="Edit Item"
                   Command="{Binding EditItemCommand, Mode=OneWay}"
                   CommandParameter="{Binding Path=PlacementTarget.SelectedItem, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" />
<ContextMenu>

答案 4 :(得分:-1)

看看WPF CommandParameter Binding Problem。也许它可以提供一些关于发生了什么的指示。