如何以编程方式关闭 ContextMenu

How do I Programatically close ContextMenu

得到了一个弹出的上下文菜单,里面有一些控件:

<ContextMenu>
    <StackPanel Orientation="Vertical">
        <TextBox Text="{Binding Path=PlacementTarget.Tag.DataContext.AddFolderName, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"></TextBox>
        <Button Content="Create here"
            Command="{Binding Path=PlacementTarget.Tag.DataContext.AddFolderCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}">
        </Button>
    </StackPanel>
</ContextMenu>

这会在用户单击鼠标右键时打开和关闭,一切都很好。但是,如果用户也按下按钮,我想关闭此菜单。

我以前用按钮点击弹出窗口做过这个——如果用户点击一个按钮打开一个弹出窗口,你可以有一个 IsOpen 布尔值 属性,它在执行的命令中设置为 true,显示弹出。

但是似乎没有等效的方法可以访问上下文菜单上的 "menu open" 功能。至少我找不到。谁能指出我正确的方向?

There is an IsOpen in ContextMenu too. 您可以将它绑定到 ViewModel 中的 属性,就像绑定命令一样,并让 AddFolderCommand 将 属性 设置为 false。例如:

<ContextMenu IsOpen="{Binding Path=PlacementTarget.Tag.DataContext.IsOpen, Mode=TwoWay
             RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}">

然后在 AddFolderCommand.Execute 你可以做 IsOpen = false.

前提是 PlacementTarget.Tag.DataContext 实际上是您需要的 ViewModel。请注意 ContextMenu 使用它自己的 window 来阻止 DataContext 继承。你有几种选择来解决这个问题:

  • 在绑定中使用 ElementName 显式引用另一个元素或其 DataContextDataContext="{Binding ElementName=other, Path=DataContext}"/>
  • 使用父级 属性 访问声明 ContextMenu 的元素:{Binding Path=Parent.DataContext, RelativeSource={RelativeSource Self}}
  • 使用静态 ViewModel:DataContext={Binding Source={x:Static local:YourStaticViewModel}

如果您不想从 ViewModel 执行此操作,则可以使用代码隐藏中的事件:只需为 ContextMenu 命名,以便您可以从代码隐藏中访问它,处理按钮上的点击事件,然后在事件处理程序上将 IsOpen 设置为 false。

您可以使用 可见性 属性:

myContextMenu.Visibility = Visibility.Collapsed;