42

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

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

显示菜单时,任务栏上添加了一个额外的图标。

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

是否有可能只调用菜单但是内置的右键单击处理程序正在执行它?

4

4 回答 4

90

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

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

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

在您自己的代码中调用此解决方法非常痛苦,pinvoke 令人不快。NotifyIcon 类在其ShowContextMenu() 方法中具有此解决方法,但由于它是私有方法,因此很难访问。反射可以绕过这个限制。我在 5 年前发现了这个 hack,但还没有人报告它有问题。设置 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);
      }
    }
于 2010-02-05T17:07:05.267 回答
2

您可以在 onClick 事件中连接通知图标,然后在单击时调用 show

private void wire()
{
     notifyIcon1.Click += new EventHandler(notifyIcon1_Click);
}

void notifyIcon1_Click(object sender, EventArgs e)
 {
    contextMenuStrip1.Show(Cursor.Position);
 }
于 2010-02-05T17:02:04.290 回答
2

如果您处理的是 MouseUp 而不是 Click,您将能够判断单击了哪个按钮以及单击的位置。您可以使用此位置作为显示 ContextMenu 的位置

notifyIcon.MouseUp += new MouseEventHandler(delegate(object sender, MouseEventArgs e) { contextMenu.Show(e.Location); });
于 2010-02-05T17:03:21.400 回答
2

使用以下代码在左右单击 notifyicon 时显示上下文菜单,如果您发现任何问题,请发短信给我 arshad_mcs786@hotmail.com (arshad from Islamabd)
//System.Runtime.InteropServices 使用 thi 作为参考

    [DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
    public static extern bool SetForegroundWindow(HandleRef hWnd);

    private void notifyIcon1_Click(object sender, EventArgs e)
    {
        SetForegroundWindow(new HandleRef(this, this.Handle));
        int x = Control.MousePosition.X;
        int y = Control.MousePosition.Y;
         x = x - 10;
        y = y - 40;
        this.contextMenuStrip1.Show(x,y );
        //this.PointToClient(Cursor.Position)
    }
于 2014-10-30T05:33:26.753 回答