【问题标题】:NotifyIcon ContextMenu and too many click eventsNotifyIcon ContextMenu 和太多的点击事件
【发布时间】:2011-10-17 18:00:06
【问题描述】:

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

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

【问题讨论】:

    标签: c# .net winforms wcf


    【解决方案1】:

    通过将上下文菜单分配给 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 事件。
    • 您是否正在处理 trayIcon_IconClicked 事件的单击处理程序中的右键单击?如果是这样,不要。设置 ContextMenu 属性会自动处理分配上下文菜单的任何控件的右键单击事件,因此您不再需要处理它。这就是它在trayIcon_IconClicked 事件中被省略的原因,因为您只是在复制事件。试试看,让我知道。
    • 我没有手动处理点击,我设置了 ContextMenu 属性,但是当用户从上下文菜单中选择一个项目时,它给出了触发 trayIcon_IconClicked 事件的行为。上面的示例不起作用,因为“this”是一个 Application 对象。我将尝试使用 ContextMenuStrip,看看效果是否更好。
    【解决方案2】:

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

    我对这个问题的解决方案是更改我用来显示左键单击上下文菜单的事件。我没有使用 Click 事件处理程序,而是使用 MouseUp 并检查单击了哪个 MouseButton。

    构建 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;
                }
            }
    

    【讨论】:

      猜你喜欢
      • 2012-01-24
      • 1970-01-01
      • 2012-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多