如何将ContextMenuStrip附加到NotifyIcon?

4

我正在尝试使一个NotifyIcon显示一个上下文菜单,即使它是通过左键点击的。 我可以在图标的MouseDown事件中使用以下代码将其显示在正确的位置:

sysTrayIcon.ContextMenuStrip = TrayContextMenu
If e.Button = MouseButtons.Left Then TrayContextMenu.Show()

但是因为当我左键点击时不会将sysTrayIcon指定为控件,所以如果我在菜单外面点击或按下esc键,它就不会从屏幕上清除。

我知道通常的方法是使用菜单重载的Show(control, location)方法,但这会引发错误:

Value of type 'System.Windows.Forms.NotifyIcon' cannot be converted to 'System.Windows.Forms.Control'.

那么,我该如何将菜单附加到通知图标呢?
1个回答

8

是的,正如所示,这段代码无法正确运行。需要使用几个秘密咒语才能在正确位置获取上下文菜单,并设置正确的鼠标捕获,以便在菜单外单击时正常工作。这些咒语是必需的,因为管理通知图标的是Windows Explorer而不是您的程序。

您需要让NotifyIcon类来处理这个问题。然而,一个重要的障碍是它并没有公开显示上下文菜单的方法,它是一个私有方法。您唯一能做的就是使用Reflection来调用该方法。像这样(使用默认名称):

Imports System.Reflection
...
    Private Sub NotifyIcon1_MouseDown(sender As Object, e As MouseEventArgs) Handles NotifyIcon1.MouseDown
        NotifyIcon1.ContextMenuStrip = ContextMenuStrip1
        Dim mi = GetType(NotifyIcon).GetMethod("ShowContextMenu", BindingFlags.NonPublic Or BindingFlags.Instance)
        mi.Invoke(NotifyIcon1, Nothing)
    End Sub

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