WPF绑定命令到ContextMenu

本文关键字:ContextMenu 命令 绑定 WPF | 更新日期: 2023-09-27 18:17:20

我在WPF中有一个命令绑定问题。我有以下xaml:

<ItemsControl ItemsSource="{Binding Entity}" Name="Lst">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>                    
                <Button  Content="qwerty" Command="{Binding ElementName=Lst, Path=DataContext.SaveCommand}" >
                    <Button.ContextMenu>
                        <ContextMenu>                                
                            <MenuItem Header="Send2" Command="{Binding ElementName=Lst, Path=DataContext.SaveCommand}" />
                        </ContextMenu>
                    </Button.ContextMenu>    
                </Button>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

可以看到Button和它的ContextMenu有类似的命令绑定。但是当我点击按钮,它的命令是发射,当我点击上下文菜单的项目,它的命令不是发射。我哪里错了?提前感谢!

WPF绑定命令到ContextMenu

我以前遇到过类似的问题,并通过通过容器的标记属性传递数据上下文来解决它,如下所示。我有它的工作在一个网格上下文菜单,但没有看到任何原因,为什么这不会工作在一个按钮。如果您有任何问题,请告诉我。

<Button  Content="qwerty" Tag="{Binding DataContext,ElementName=Lst}" Command="{Binding ElementName=Lst, Path=DataContext.SaveCommand}"  >
                    <Button.ContextMenu>
                        <ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">                                
                            <MenuItem Header="Send2" Command="{Binding SaveCommand}" />
                        </ContextMenu>
                    </Button.ContextMenu>    
                </Button>

由于ContextMenu与可视化树是分开的,所以您不能绑定它之外的任何元素。

如果你检查你的输出窗口,你应该有一个消息说它找不到对象"Lst"

一个常见而简单的解决方法是在代码后手动设置DataContext(注意:这根本不会破坏MVVM)。你只是在执行一个将DataContexts链接在一起的纯UI操作):

在你的Xaml:

<Button.ContextMenu>
                        <ContextMenu Opened="OnContextMenuOpened">                                
                            <MenuItem Header="Send2" Command="{Binding ElementName=Lst, Path=DataContext.SaveCommand}" />
                        </ContextMenu>
                    </Button.ContextMenu>
在后台代码:

public void OnContextMenuOpened(object sender, RoutedEventArgs args)
{
    (sender as ContextMenu).DataContext = Lst.DataContext;
}

因此,每次打开ContextMenu时,您都链接DataContext(因此,如果Lst的DataContext更改,您的ContextMenu也将更改)

或者(如果您一定要多次使用它,则更干净),从本文中获取BindingProxy: http://tomlev2.wordpress.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/,它将奏效!