通知图标事件未触发

4

我是一个新手,有一个非常神秘的问题需要解决。我是英国的软件开发人员,拥有超过15年的经验,但只有18个月的.Net开发经验。我的NotifyIcon鼠标事件不起作用!

我使用C#编写一个应用程序,它以NotifyIcon(“主应用程序图标”)启动,并在鼠标右键单击时显示ContextMenu。这很好用:ContextMenu、窗体启动和鼠标单击事件都能正常工作。

一点背景:该应用程序应该检测到usb“设备”的插入(它确实),对其进行询问并创建另一个NotifyIcon(“设备图标”),以允许用户与该设备交互。在上一段中提到的“主应用程序图标”允许用户与数据库交互并配置软件。

为了封装这些设备交互功能,我构建了一个“设备类”,其中包含设备NotifyIcon、ContextMenu、窗体、鼠标点击事件等,以允许与设备进行交互。

问题 问题出现在我从ManagementEventWatcher EventArrived事件中实例化我的“设备类”。如果我在程序Main中实例化“设备类”,则单击notifyicon时事件会正确触发。

所以,请有人帮帮我吗?

提前感谢!

马修

3个回答

3
我记得使用事件(而不是WaitForNextEvent)可以异步工作。我很想知道事件在哪个线程上被引发。我想知道您的图标是否没有为消息提供服务的消息泵。
您是否有任何窗体?或者其他带有消息循环的东西?我会尝试调用窗体(使用Control.Invoke),并要求窗体显示图标,因为这样它应该有一个活动的消息泵。
抱歉让您久等了;根据您的评论,听起来您已经有了一个解决方法。唯一需要注意的是跨线程问题;理想情况下,您应该请求UI以UI线程方式进行此类更改;例如,如果您有一个拥有该图标的Form - 请添加到您的窗体类:
// not a property, as there is no need to add a complex x-thread "get"
public void SetIconVisible(bool isVisible) {
    if(this.InvokeRequired) {
        this.Invoke((MethodInvoker) delegate {
            myIcon.Visible = isVisible;
        });
    } else {
        myIcon.Visible = isVisible;
    }
}

这将执行一个线程切换(如果需要)到UI线程。有什么用吗?

嗨,马克 感谢您的快速回复! 我对此还不太熟悉,无法回答您的问题或理解建议。 有没有什么方法可以让我制作您所说的“消息泵”?我确实有表单,但它们只是响应我提到的上下文菜单而显示。您在第二句中询问的是哪个事件?干杯 M - user188999
谢谢Mark。我的研究告诉我我需要做一些跨线程操作——这是我刚刚理解的。关于委托和调用之类的东西?希望有所帮助。 - user188999
Mark,我想告诉你 - 我已经想出了一个方法,可以在主线程中创建具有NotifyIcon成员的类实例,然后在连接USB设备时使NotifyIcon(s)可见。不过需要进行一些调整,因为当第一次显示NotifyIcon时才会创建它,所以我必须确保为每个NotifyIcon先将Visible设置为true,然后再设置为false。当设备连接时,ManagementEventWatcher线程可以将Visible属性设置为true。这是一个解决方法。 - user188999
我非常有兴趣知道如何在主线程中实例化类(以便事件触发),但是如果您有时间帮忙,可以从ManagementEventWatcher线程开始启动吗? - user188999

1

所以答案是:

只有在主线程中使NotifyIcon可见时,事件才能正常工作。因此,由Marc Gravell提供的代码是解决方案。


0

马克,我想让你知道 -

我发现我可以在主线程中创建具有NotifyIcon成员的类实例,然后在连接USB设备时使NotifyIcon(s)可见。

不过需要进行一些调整,因为当第一次显示NotifyIcon时才会创建它,所以我必须确保(在主线程中)对每个实例将Visible设置为true,然后再设置为false - 这就需要限制实例数量。

当设备连接时,ManagementEventWatcher线程可以将Visible属性设置为true。

这是一个解决方法。

(请参见您评论的回复)


添加了一些想法 - 希望能有所帮助。 - Marc Gravell

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