12

我正在使用 System.Windows.Forms.ContextMenu。我想这样做,所以当您单击某些按钮时,它不会关闭菜单。现在我让它工作,只要你点击一个,它就会在相同的位置重新打开菜单。唯一的问题是它看起来很糟糕,因为您可以看到菜单闪烁。有没有更好的方法来做到这一点?

WPF 的 ContextMenu 具有 StaysOpen 属性,但 Win Forms 没有。(有什么方法可以使用 WPF 的 ContextMenu 吗?)我不想使用 ContextMenuStrip,它可以做到这一点,因为 ContextMenu 看起来好多了。

编辑:

我不会将此标记为解决方案,因为这样做不好。如果您需要执行我的问题,一种方法是从 WPF 创建一个 UserControl,然后将带有上下文菜单的对象放入其中,然后将上下文菜单添加到其中。现在因为它在 WPF 中,所以在您不想在单击时关闭菜单的按钮上,将 MenuItem 上的属性 StaysOpenOnClick 设置为 true。然后只需将此 UserControl 放入您的 WinForms 应用程序。

4

3 回答 3

21

您可以像这样保持上下文菜单打开:

private bool CloseContextMenu = true; //Class Variable

然后将 MouseDown 添加到您的上下文菜单项中:

private void menu1ToolStripMenuItem_MouseDown(object sender, MouseEventArgs e)
{
    CloseContextMenu = false;
}

然后在您的上下文菜单关闭事件中:

private void contextMenuStrip1_Closing(object sender, ToolStripDropDownClosingEventArgs e)
{
    e.Cancel = !CloseContextMenu;
    CloseContextMenu = true;
}

然后,您可以将 添加CloseContextMenu = false到您想要的任何菜单事件中。

希望这可以帮助。

于 2012-07-25T20:37:42.503 回答
6

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是类似于您描述的黑客 - 存储菜单的先前位置,并在选择命令后重新显示弹出窗口-上一个位置的菜单。无论您想出什么治疗闪烁的方法(例如,冻结屏幕并抑制重绘,直到重新显示上下文菜单)几乎都肯定会比疾病更糟。

于 2012-07-25T20:51:27.237 回答
-2

我刚刚添加

ContextMenuStrip1.Show();

在我的点击事件中。当我单击上下文菜单时,它会关闭,但会立即打开,因此它实际上保持打开状态。

于 2014-01-20T05:09:05.370 回答