WPF ContextMenu Click 事件仅在背景网格的 MouseMove 事件之后触发

问题描述 投票:0回答:1

我有网格。在其中,我打开一个上下文菜单。当我单击一个菜单项时,会按顺序发生以下情况: (1) 触发网格的 MouseMove 事件; (2) 触发MenuItem的Click事件;最后,(3) 菜单关闭。

我预计事件 (2) 和 (3) 在 (1) 之前发生。为什么会发生这种情况?有没有办法让菜单“阻止”后台事件直到关闭?

c# wpf contextmenu mahapps.metro
1个回答
0
投票

在 WinForms 或 WPF 等用户界面框架中触发事件的顺序有时可能会出乎意料,特别是当来自不同控件的事件相互交互时。在这种情况下,并不是菜单“阻止”后台事件直到其关闭,而是框架的事件处理机制可能导致事件按特定顺序进行处理。

典型的 Windows 窗体 (WinForms) 应用程序中的事件处理顺序如下:

鼠标按下 鼠标按下 单击(如果 MouseDown 和 MouseUp 发生在同一控件中) 鼠标移动 在您的场景中,当您打开上下文菜单并单击 MenuItem 时,MouseMove 事件可能会在 MenuItem 的 Click 事件之前触发,因为鼠标按钮被按下,然后在您单击 MenuItem 时释放。此顺序遵循典型的事件顺序。

没有一种内置方法可以轻松更改框架处理事件的顺序。但是,您可以通过在打开上下文菜单时设置一个标志并在关闭它时清除它来解决此问题。在 MouseMove 事件处理程序中,您可以检查此标志以确定在菜单打开时是否应处理或忽略该事件。

这是一个用 C# 编写的简化示例:

 private bool contextMenuOpen = false;

    private void contextMenu_Opening(object sender, CancelEventArgs e)
    {
        contextMenuOpen = true;
    }

private void contextMenu_Closed(object sender, ToolStripDropDownClosedEventArgs e)
{
    contextMenuOpen = false;
}

private void grid_MouseMove(object sender, MouseEventArgs e)
{
    if (contextMenuOpen)
    {
        // Ignore MouseMove events while the context menu is open.
        return;
    }

    // Your MouseMove event handling code here.
}

private void menuItem_Click(object sender, EventArgs e)
{
    // Handle the MenuItem's Click event.
}
private bool contextMenuOpen = false;

private void contextMenu_Opening(object sender, CancelEventArgs e)
{
    contextMenuOpen = true;
}

private void contextMenu_Closed(object sender, ToolStripDropDownClosedEventArgs e)
{
    contextMenuOpen = false;
}

private void grid_MouseMove(object sender, MouseEventArgs e)
{
    if (contextMenuOpen)
    {
        // Ignore MouseMove events while the context menu is open.
        return;
    }

    // Your MouseMove event handling code here.
}

private void menuItem_Click(object sender, EventArgs e)
{
    // Handle the MenuItem's Click event.
}

在此示例中,当打开上下文菜单时,contextMenuOpen 标志设置为 true,并在菜单关闭时清除。在 grid_MouseMove 事件处理程序中,我们检查标志并避免在上下文菜单打开时处理该事件。

© www.soinside.com 2019 - 2024. All rights reserved.