I'm new here and have a really mysterious problem to start off. I'm a software developer in the UK and have over 15 years of experience but have only been developing in .Net for 18 months. My NotifyIcon mouse events are not firing!
I am using C# to write an application that starts as a NotifyIcon ('main app icon') and displays a ContextMenu on mouse right-click. This works fine: ContextMenu, 开发者_Python百科forms launching and mouse click events firing.
A tiny bit of background: the application is supposed to sense the insertion of a usb 'device' (it does), interrogate it and create another NotifyIcon ('device icon') to allow the user to interact with that device. The 'main app icon', mentioned in my previous paragraph, allows the user to interact with the database and to configure the software.
To encapsulate these device interaction functions, I have constructed a 'device class' that contains the device NotifyIcon, ContextMenu, forms, mouse click events etc which allow interaction with the device.
The Problem The problem starts when I instantiate my 'device class' from the ManagementEventWatcher EventArrived event. If I instantiate the 'device class' in my program Main then the events fire correctly when I click the notifyicon.
So, please, can someone help me?
Cheers, in advance
Matthew
IIRC, the event usage (rather than WaitForNextEvent
) works async. I would be interested to know what thread the event is being raised on. I wonder if there is no message pump servicing messages for your icon.
Do you have a form anywhere? Or something else with a message loop? I would be tempted to call into the form (using Control.Invoke
), and ask the form to show the icon - since then it should have an active message pump.
Sorry for the delay; reading your comments, it sounds like you've broadly got a workaround. The only gotcha is cross-threaded issues; ideally, you would ask the UI to make such a change on the UI thread; for example, if you have a Form
kicking around (owning the icon) - add to your form class:
// 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;
}
}
This does a thread-switch (if needed) to the UI thread. Any use?
So the answer is:
The events will only work if when you make the NotifyIcon visible, you do it in the main thread. So the code given by Marc Gravell is the solution.
Mark, just to let you know -
I worked out that I could create the class instances that have the NotifyIcon as members in the main thread and then make the NotifyIcon(s) visible when the USB device(s) are connected.
It needed a bit of adjustment though because the NotifyIcon is created when it's first made visible, so I had to make sure that (in the main thread) I set Visible to true then to false for each - giving rise to the need for limiting the number of instances.
The ManagementEventWatcher thread could then set the Visible property to true when the device gets connected.
A workaround.
(see replies to your comments)
精彩评论