如何在程序中以编程方式打开上下文菜单时触发ContextMenuOpening事件

6
当我使用<control>.ContextMenu.IsOpen = true打开上下文菜单时,上下文菜单变为可见状态,但是没有触发打开或关闭事件。
如何确保在以编程方式打开上下文菜单时触发ContextMenuOpeningContextMenuClosing事件?

演示:

请查看以下XAML代码:
<Button Name="ContextMenuButton" 
        Content="Click me!" 
        Click="ContextMenuButton_Click" 
        ContextMenuOpening="ContextMenuButton_OnContextMenuOpening"
        ContextMenuClosing="ContextMenuButton_OnContextMenuClosing">
    <Button.ContextMenu>
        <ContextMenu>
            <MenuItem Header="First element" />
            <MenuItem Header="Second element" />
        </ContextMenu>
    </Button.ContextMenu>
</Button>

以下是与此相关的代码:

public MainWindow() // Constructor
{
    InitializeComponent();
    ContextMenuButton.ContextMenuOpening += (sender, args) => Debug.Print("Opening #2");
    ContextMenuButton.ContextMenuClosing += (sender, args) => Debug.Print("Closing #2");
}

private void ContextMenuButton_Click(object sender, RoutedEventArgs e)
{
    Button button = (sender as Button);
    button.ContextMenu.IsOpen = true; // How should I open the ContextMenu?
}

private void ContextMenuButton_OnContextMenuOpening(object sender, ContextMenuEventArgs e)
{
    Debug.Print("Opening #1");
}

private void ContextMenuButton_OnContextMenuClosing(object sender, ContextMenuEventArgs e)
{
    Debug.Print("Closing #1");
}

右键单击按钮时的行为:

上下文菜单将打开。

输出结果是:

Opening #1
Opening #2
Closing #1
Closing #2

点击按钮时的行为:

上下文菜单会打开。

输出结果为:

<Nothing>
2个回答

4
问题在于您在按钮的ContextMenuOpening事件上附加了事件,由于您手动调用了ContextMenu,因此事件没有触发。所以要获取事件,请附加ContextMenu的Opened和Closed事件。
    public MainWindow() // Constructor
    {
        InitializeComponent();
        ContextMenuButton.ContextMenu.Opened += (sender, args) => Debug.Print("Opening #2");
        ContextMenuButton.ContextMenu.Closed += (sender, args) => Debug.Print("Closing #2");
    }

xaml

    <Button Name="ContextMenuButton" 
            Content="Click me!" 
            Click="ContextMenuButton_Click" >
        <Button.ContextMenu>
            <ContextMenu Opened="ContextMenuButton_OnContextMenuOpening" Closed="ContextMenuButton_OnContextMenuClosing">
                <MenuItem Header="First element" />
                <MenuItem Header="Second element" />
            </ContextMenu>
        </Button.ContextMenu>
    </Button>

事件,ContextMenuEventArgs已更改为RoutedEventArgs

    private void ContextMenuButton_OnContextMenuOpening(object sender, RoutedEventArgs e)
    {
        Debug.Print("Opening #1");
    }

    private void ContextMenuButton_OnContextMenuClosing(object sender, RoutedEventArgs e)
    {
        Debug.Print("Closing #1");
    }

这应该解决你的问题。


1

Opened和Opening事件是有区别的。通常,在菜单显示之前,Opening事件用于动态构建菜单。在这种情况下,上述解决方案将无法工作。

`
 // Raise Context menu Opening Event
 var args = CreateInstance<ContextMenuEventArgs>(element, true);
 args.RoutedEvent = FrameworkElement.ContextMenuOpeningEvent;
 element.RaiseEvent(args);
 
 contextMenu.IsOpen = true;
`

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