调用NotifyIcon的上下文菜单

Bar*_*ttJ 40 c# notifyicon winforms

我想让它左键单击NotifyIcon也会导致上下文菜单(使用ContextMenuStrip属性设置)也打开.我怎么做到这一点?我是否必须自己处理Click并找出定位?
编辑:使用trayIcon.ContextMenuStrip.Show()显示菜单结果是一些不良行为:

菜单未显示在同一位置,就像右键单击NotifyIcon一样(看起来您无法将x和y坐标设置为任务栏所在的位置,至少在我正在运行的Windows 7上).它将显示在任务栏上方(不是很大的交易,但一致性会很好).

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

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

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

Han*_*ant 85

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

    private void notifyIcon1_MouseClick(object sender, MouseEventArgs e) {
        contextMenuStrip1.Show(Control.MousePosition);
    }
Run Code Online (Sandbox Code Playgroud)

但实际上并没有正常工作,当你在它外面点击时,CMS就不会关闭.底层问题是这个知识库文章中描述的Windows怪癖(又名"bug").

在您自己的代码中调用此变通办法非常痛苦,pinvoke令人不快.NotifyIcon类在其ShowContextMenu()方法中有这种解决方法,它们只是很难到达,因为它是一个私有方法.反思可以绕过这种限制.我5年前发现了这个黑客,没有人报告它有问题.设置NFI的ContextMenuStrip属性并实现MouseUp事件,如下所示:

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);
      }
    }
Run Code Online (Sandbox Code Playgroud)

  • 这完全是胡说八道. (5认同)