在自定义控件中正确绑定ContextMenu

时间:2015-03-19 16:39:14

标签: wpf binding contextmenu

我无法在自定义控件中找到ContextMenu菜单项的正确绑定。

<ContextMenu x:Key="MyContextMenu">
    <MenuItem Header="MyMenuItem"
              Command="{Binding PlacementTarget.MyCommand, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"/>
</ContextMenu>

<Style TargetType="{x:Type local:MyControl}" x:Shared="False">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyControl}">
                <DockPanel ContextMenu="{StaticResource MyContextMenu}">
                    <!--some controls-->
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

MyCommand在MyControl.xaml.cs中定义,是我希望绑定到菜单项的命令。

示例中的绑定在DockPanel中查找MyCommand。什么是正确的绑定?

3 个答案:

答案 0 :(得分:1)

您需要在菜单的容器中添加标签,并使用展示位置目标绑定到该容器。

查看此示例:

<StackPanel x:Key="ConfigurationListItem" x:Shared="False" Tag="{Binding ElementName=UserControl}">
        <StackPanel.ContextMenu>
            <ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}" Tag="{Binding}">
                <MenuItem Header="Sync Environment Dependencies" 
                        Command="{Binding Parent.PlacementTarget.Tag.SyncEnvironmentCommand, RelativeSource={RelativeSource Self}}"
                        CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.DataContext}" />
            </ContextMenu>
        </StackPanel.ContextMenu>
    </StackPanel>

答案 1 :(得分:0)

ContextMenu不包含在VisualTree中。因此没有datacontext .. 这样做是为了让它工作..

<MenuItem Command="{Binding Path=PlacementTarget.DataContext.MyCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />

答案 2 :(得分:0)

先生。尼姆罗德的答案并没有完全解决我的问题,但提供了这样做的技巧。以下是有效的。

ContextMenu的问题在于你不能使用RelativeSource将元素树遍历到任意控件:你只能到它的容器(你用PlacementTarget引用)。

基本策略是在ContextMenu的容器中分配Tag。 Tag指的是你感兴趣的任何控件,命令等。在我的情况下,我将它分配给TemplatedParent,它允许我绑定到MenuItem.Command到MyCommand。

<Style TargetType="{x:Type local:MyControl}" x:Shared="False">
    <Style.Resources>
        <ResourceDictionary>
            <ContextMenu x:Key="MyContextMenu">
                <MenuItem Header="MyItem"
                          Command="{Binding Parent.PlacementTarget.Tag.MyCommand, RelativeSource={RelativeSource Self}}"/>
            </ContextMenu>
        </ResourceDictionary>
    </Style.Resources>

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyControl}">                
                <DockPanel ContextMenu="{StaticResource MyContextMenu}" Tag="{Binding RelativeSource={RelativeSource TemplatedParent}}">
                    <!--some controls-->                
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>