调用 NotifyIcon 的上下文菜单 [英] Invoke NotifyIcon's Context Menu

查看:23
本文介绍了调用 NotifyIcon 的上下文菜单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望左键单击 NotifyIcon 也会打开上下文菜单(使用 ContextMenuStrip 属性设置).我将如何实现这一目标?我是否必须自己处理 Click 并确定定位?
显示带有trayIcon.ContextMenuStrip.Show() 结果的菜单是一些不良行为:

I want to have it such that left clicking on the NotifyIcon also causes the context menu (set with the ContextMenuStrip property) to open as well. How would I achieve this? Do I have to handle Click and figure out the positioning myself?
showing the menu with trayIcon.ContextMenuStrip.Show() results is a few undesirable behaviors:

菜单未显示在与右键单击 NotifyIcon 相同的位置(似乎您无法将 x 和 y 坐标设置为任务栏所在的位置,至少在我正在运行的 Windows 7 上)).它会出现在任务栏上方(没什么大不了,但一致性会很好).

The menu is not shown at the same location as if right click the NotifyIcon (it appears that you can't set the x and y coords to where the taskbar is, at least on Windows 7 which is what I'm running). It will appear above the task bar (not that big of a deal, but consistency would be nice).

在显示菜单时,任务栏中添加了一个额外的图标.

While the menu is shown, there is an extra icon added to the task bar.

单击菜单以外的其他位置不会关闭它(而如果您右键单击以调出上下文菜单,单击其他位置会自动关闭上下文菜单).

Clicking somewhere other than the menu does not close it (whereas if you right click to bring up the context menu clicking else where automatically closes the context menu).

是否可以只调用菜单但内置的右键单击处理程序正在执行此操作?

Is it at all possible to just invoke the menu however the built in right click handler is doing it?

推荐答案

您通常会处理 MouseClick 事件以检测单击并调用 ContextMenuStrip.Show() 方法:

You would normally handle the MouseClick event to detect the click and call the ContextMenuStrip.Show() method:

    private void notifyIcon1_MouseClick(object sender, MouseEventArgs e) {
        contextMenuStrip1.Show(Control.MousePosition);
    }

但这实际上并不能正常工作,当您在其外部单击时,CMS 不会关闭.根本问题是 这篇知识库文章中描述的 Windows 怪癖(又名错误").

But that doesn't actually work properly, the CMS won't close when you click outside of it. Underlying issue is a Windows quirk (aka "bug") that is described in this KB article.

在您自己的代码中调用此解决方法非常痛苦,pinvoke 令人不快.NotifyIcon 类在其 ShowContextMenu() 方法,他们只是难以访问,因为它是一个私有方法.反射可以绕过该限制.我在 5 年前发现了这个 hack,但还没有人报告它的问题.设置 NFI 的 ContextMenuStrip 属性并像这样实现 MouseUp 事件:

Invoking this workaround in your own code is pretty painful, the pinvoke is unpleasant. The NotifyIcon class has this workaround in its ShowContextMenu() method, they just made it difficult to get to since it is a private method. Reflection can bypass that restriction. I discovered this hack 5 years ago and nobody reported a problem with it yet. Set the NFI's ContextMenuStrip property and implement the MouseUp event like this:

using System.Reflection;
...
    private void notifyIcon1_MouseUp(object sender, MouseEventArgs e) {
      if (e.Button == MouseButtons.Left) {
        MethodInfo mi = typeof(NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.Instance | BindingFlags.NonPublic);
        mi.Invoke(notifyIcon1, null);
      }
    }

这篇关于调用 NotifyIcon 的上下文菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆