ContextMenu
使用控件没有很好的方法来做到这一点。那个只是原生 Win32 菜单的包装,这就是为什么它看起来好多了。它使用 OS API 绘制,就像所有其他应用程序中的菜单一样。
将其与ContextMenuStrip
由框架在 C# 代码中完全自定义绘制的控件进行比较。当它第一次发布时,它看起来超级酷(我猜),当时 Windows 和 Office XP 是货架上的最新产品。当 Windows Vista 推出时,它已经过时了。它的唯一优点是您可以对菜单进行更细粒度的控制。例如,您可以在菜单中托管自定义控件,并且可以在单击其中一项时阻止菜单关闭。本机 Win32 菜单不支持该功能。
当然,这不仅仅是疏忽或意外遗漏。在用户已经选择了一些东西之后保持上下文菜单打开的愿望是一个很好的线索,表明你的设计是错误的。请记住,上下文菜单的目的是让用户快速访问上下文相关的选项。他们所要做的就是右键单击(或按键盘上的特殊按钮),他们可以看到与他们正在处理或试图完成的任务直接相关的选项菜单。就像常规菜单一样,他们应该能够选择一个选项并让菜单消失。
在 Windows 中,所有菜单都是“自动关闭”的。如果菜单应该是持久的,那么它根本不应该是菜单。考虑改用工具栏、侧边栏或某种类型的自定义控件。Those aren't designed to go away when one of their options are selected, and therefore they're ideal for showing related options that should always be visible.
如果在我选择一个选项后应用程序中的上下文菜单没有消失,我会认为这是一个错误。至少,我会假设我的选择没有“接受”并尝试再次单击它。
我一点也不知道为什么 WPF 团队决定StaysOpen
为他们的上下文菜单提供一个选项,或者为什么他们首先重写了自己的上下文菜单类。他们不是从已经做过同样事情的 WinForms 团队那里学到了一些东西吗?
使用控件(以及因此本机菜单)执行您所要求的唯一方法ContextMenu
是类似于您描述的黑客 - 存储菜单的先前位置,并在选择命令后重新显示弹出窗口-上一个位置的菜单。无论您想出什么治疗闪烁的方法(例如,冻结屏幕并抑制重绘,直到重新显示上下文菜单)几乎都肯定会比疾病更糟。