NotifyIcon上下文菜单和过多的点击事件

5

我正在使用NotifyIcon类在任务栏中显示一个图标。该图标执行两个功能 - 当用户使用左键单击时,应该显示一个窗口;当用户使用右键单击时,应该显示上下文菜单。这个代码在除了用户点击上下文菜单选项后显示窗口之外都可以正常工作。以下是我的代码:

contextMenuItems = new List<MenuItem>();
contextMenuItems.Add(new MenuItem("Function A", new EventHandler(a_Clicked)));
contextMenuItems.Add(new MenuItem("-"));
contextMenuItems.Add(new MenuItem("Function B", new EventHandler(b_Clicked)));
trayIcon = new System.Windows.Forms.NotifyIcon();
trayIcon.MouseClick += new MouseEventHandler(trayIcon_IconClicked);
trayIcon.Icon = new Icon(GetType(), "Icon.ico");
trayIcon.ContextMenu = contextMenu;
trayIcon.Visible = true;

问题在于当用户选择“功能A”或“功能B”时,我的trayIcon_IconClicked事件就会触发。为什么会这样呢?
谢谢, J
2个回答

3
通过将上下文菜单分配给NotifyIcon控件,它会自动捕获右键单击并在那里打开分配的上下文菜单。如果您想在实际显示上下文菜单之前执行一些逻辑,则将委托分配给contextMenu.Popup事件即可。
...
contextMenu.Popup += new EventHandler(contextMenu_Popup);
...

private void trayIcon_IconClicked(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        //Do something here.
    }
    /* Only do this if you're not setting the trayIcon.ContextMenu property, 
    otherwise use the contextMenu.Popup event.
    else if(e.Button == MouseButtons.Right)
    {
        //Show uses assigned controls Client location to set position, 
        //so must go from screen to client coords.
        contextMenu.Show(this, this.PointToClient(Cursor.Position));
    }
    */
}

private void contextMenu_Popup(object sender, EventArgs e)
{
    //Do something before showing the context menu.
}

我猜测弹出窗口的原因可能是你打开的上下文菜单将NotifyIcon用作目标控件,因此当你单击它时,它会运行你分配给NotifyIcon的单击处理程序。
另一个可以考虑的选项是使用ContextMenuStrip。 NotifyIcon也有一个ContextMenuStrip属性,它似乎具有更多的与之相关的功能(我注意到我可以做更多事情,编程方面)。 如果出现问题,建议尝试使用它。

谢谢,有没有办法停止使用NotifyIcon作为目标控件?或者甚至手动弹出菜单?我尝试过ContextMenu.Show(),但它需要一个控件作为参数,并且似乎不会触发Popup事件。 - JWood
1
你是否在trayIcon_IconClicked事件的click-handler中处理了右键单击?如果是这样,请不要这么做。设置ContextMenu属性会自动处理分配了上下文菜单的任何控件的右键单击事件,因此您不再需要处理它。这就是为什么在trayIcon_IconClicked事件中省略了它,因为您只会重复事件。尝试一下并让我知道结果。 - SPFiredrake
我并没有手动处理点击事件,而是设置了ContextMenu属性,但这会在用户从上下文菜单中选择一个项目时触发trayIcon_IconClicked事件的行为。上面的示例不起作用,因为“this”是一个应用程序对象。我将尝试使用ContextMenuStrip,看看是否能获得更好的结果。 - JWood

0

我遇到了同样的问题。 将NotifyIcon的ContextMenu更改为ContextMenuStrip并没有解决问题(实际上,当我更改ContextMenu时,单击事件发生在ContextMenuStrip显示而不是用户实际单击其中一个项目时)。

我的解决方法是更改我用于显示左键单击上下文菜单的事件。我使用MouseUp而不是Click事件处理程序,并检查哪个鼠标按钮被单击。

构建NotifyIcon(notifyContext是System.Windows.Forms.ContextMenuStrip)

m_notifyIcon.MouseUp += new Forms.MouseEventHandler(m_notifyIcon_MouseUp);
m_notifyIcon.ContextMenuStrip = notifyContext;

Handling the left click event and show the main contextmenu:

        void m_notifyIcon_MouseUp(object sender, Forms.MouseEventArgs e)
        {
            if (e.Button == Forms.MouseButtons.Left)
            {
                mainContext.IsOpen = ! mainContext.IsOpen;
            }
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接