如何将命令绑定到菜单项(WPF)?

11

这是我从View.xaml.cs中提取的代码:

private RelayCommand _closeCommand;
public ICommand CloseCommand
{
    get
    {
        if (_closeCommand == null)
        {
            _closeCommand = new RelayCommand(param => this.OnClose());
        }
        return _closeCommand;
    }
}

public void OnClose()
{
    Close();
}

以下是我的 View.xaml 代码:

<Window.ContextMenu>
    <ContextMenu>
        <MenuItem Name="menuItem_Close" Header="Close" Command="{Binding CloseCommand}" />
    </ContextMenu> 
</Window.ContextMenu>

当我运行程序并选择关闭菜单项时,什么也没发生。甚至没有执行CloseCommand代码。

你设置了DataContext吗? - Bob.
1
我找到了解决我的问题的方法。我正在使用一个ViewModel,其中包含另一个ViewModel类型的属性,我需要通过这样做来缩小范围到该属性:Command="{Binding ActiveVM.CloseCommand}" - Jackson Dean Goodwin
我已经找到了关于你的问题[https://dev59.com/pnNA5IYBdhLWcg3wmfEa#18362041]的解决方案。 - Jacksquad
3个回答

11

ContextMenu不是VisualTree的一部分,因此DataContext不会被继承。这里ContextMenu.PlacementTarget是一种获取Window的中转。

<MenuItem Name="menuItem_Close" Header="Close"
          Command="{Binding Path=PlacementTarget.DataContext.CloseCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />

1
你确定它没有获取到 DataContext 吗?在我的测试中,它似乎像预期的那样继承了 DataContext... - McGarnagle
我尝试了你的Command="..."代码,但仍然没有用 - 就像以前一样 - 没有任何反应。 - Jackson Dean Goodwin
根据这里所述,弹出窗口(Popup)会创建自己的视觉树。这意味着在放置于Popup中的ContextMenu不会继承DataContext。 - LPL
@JacksonDeanGoodwin 有绑定错误吗?您确定Window的DataContext已设置吗?也许尝试在Window直接使用Button进行命令绑定。 - LPL
谢谢。我该如何将一个static ICommand绑定到一个MenuItem而不使用ViewModel绑定?我目前正在使用(但不起作用的)Command="{x:Static ...}",但似乎这与您在此处提供的解决方案不兼容。请帮忙。 - Agent007

0

旧问题,新答案。对我来说,问题在于GalaSoft.MvvmLight.Command.RelayCommand不支持闭包作为操作。RelayCommand将操作存储为弱引用,因此闭包几乎立即被释放。操作必须是模型方法或以其他方式保留。


-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接