C# WPF将命令绑定到上下文菜单

C# WPF将命令绑定到上下文菜单,c#,wpf,xaml,data-binding,C#,Wpf,Xaml,Data Binding,WPF中的命令绑定有问题。我有以下xaml: <ItemsControl ItemsSource="{Binding Entity}" Name="Lst"> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel> <Button Content="qwerty" C

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>


正如您所看到的,按钮及其ContextMenu具有类似的命令绑定。但当我点击按钮时,它的命令会被触发,而当我点击上下文菜单的项目时,它的命令不会被触发。我错在哪里?提前谢谢

ContextMenu与可视化树是分开的,您不能与它之外的元素绑定

如果您检查输出窗口,应该会有一条消息说它找不到对象“Lst”

一个常见且简单的解决方法是在代码隐藏中手动设置DataContext(注意:这根本没有破坏MVVM。您只是在执行将DataContext链接在一起的纯UI操作):

在您的Xaml中:

<Button.ContextMenu>
                        <ContextMenu Opened="OnContextMenuOpened">                                
                            <MenuItem Header="Send2" Command="{Binding ElementName=Lst, Path=DataContext.SaveCommand}" />
                        </ContextMenu>
                    </Button.ContextMenu>
因此,每次打开
ContextMenu
时,您都会链接
DataContext
(因此,如果Lst的
DataContext
发生更改,您的ContextMenu也会更改)


或者(如果您一定要多次使用它,那么就更干净),从本文中获取
BindingProxy
:它会成功的

ContextMenu与可视化树是分开的,您不能与它之外的元素绑定

如果您检查输出窗口,应该会有一条消息说它找不到对象“Lst”

一个常见且简单的解决方法是在代码隐藏中手动设置DataContext(注意:这根本没有破坏MVVM。您只是在执行将DataContext链接在一起的纯UI操作):

在您的Xaml中:

<Button.ContextMenu>
                        <ContextMenu Opened="OnContextMenuOpened">                                
                            <MenuItem Header="Send2" Command="{Binding ElementName=Lst, Path=DataContext.SaveCommand}" />
                        </ContextMenu>
                    </Button.ContextMenu>
因此,每次打开
ContextMenu
时,您都会链接
DataContext
(因此,如果Lst的
DataContext
发生更改,您的ContextMenu也会更改)


或者(如果您一定要多次使用它,那么就更干净),从本文中获取
BindingProxy
:它会成功的

我以前也遇到过类似的问题,通过将datacontext传递给容器的tag属性解决了这个问题,如下所示。我有一个网格上下文菜单工作,但没有看到任何原因,为什么这对一个按钮不起作用。如果你有任何问题,请告诉我

<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>

我以前遇到过类似的问题,通过将datacontext传递给容器的tag属性解决了这个问题,如下所示。我有一个网格上下文菜单工作,但没有看到任何原因,为什么这对一个按钮不起作用。如果你有任何问题,请告诉我

<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>


可能重复的可能重复的是,请查看我在答案末尾发布的文章。
BindingProxy
做得很好是的,请查看我在答案末尾发布的文章。
BindingProxy
完美地做到了这一点