Invoke NotifyIcon's Context Menu

后端 未结 4 675
陌清茗
陌清茗 2020-11-29 04:32

I want to have it such that left clicking on the NotifyIcon also causes the context menu (set with the ContextMenuStrip property) to open as well. How would I achieve this?

4条回答
  •  自闭症患者
    2020-11-29 04:51

    You would normally handle the MouseClick event to detect the click and call the ContextMenuStrip.Show() method:

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

    But that doesn't actually work properly, the CMS won't close when you click outside of it. Underlying issue is a Windows quirk (aka "bug") that is described in this KB article.

    Invoking this workaround in your own code is pretty painful, the pinvoke is unpleasant. The NotifyIcon class has this workaround in its ShowContextMenu() method, they just made it difficult to get to since it is a private method. Reflection can bypass that restriction. I discovered this hack 5 years ago and nobody reported a problem with it yet. Set the NFI's ContextMenuStrip property and implement the MouseUp event like this:

    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);
          }
        }
    

提交回复
热议问题