调用NotifyIcon的上下文菜单

时间:2010-02-05 16:37:24

标签: c# winforms notifyicon

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

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

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

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

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

4 个答案:

答案 0 :(得分:83)

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

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

但实际上并没有正常工作,当您点击它之外时CMS不会关闭。基础问题是this KB article中描述的Windows怪癖(又名“bug”)。

在您自己的代码中调用此变通办法非常痛苦,pinvoke令人不快。 NotifyIcon类在ShowContextMenu() method中有这种解决方法,因为它是一个私有方法,所以它很难实现。反思可以绕过这种限制。我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);
      }
    }

答案 1 :(得分:2)

您可以在onClick事件中连接通知图标,然后在点击

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

void notifyIcon1_Click(object sender, EventArgs e)
 {
    contextMenuStrip1.Show(Cursor.Position);
 }

答案 2 :(得分:2)

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

的位置
notifyIcon.MouseUp += new MouseEventHandler(delegate(object sender, MouseEventArgs e) { contextMenu.Show(e.Location); });

答案 3 :(得分:2)

使用以下代码在右侧和左侧单击notifyicon上显示上下文菜单,如果您发现任何问题,请发送电子邮件至arshad_mcs786@hotmail.com(来自Islamabd的arshad)
//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)
    }