[英]Click event delayed in ContextMenu attached to NotifyIcon
I am working on a plugin (using System.ComponentModel.Composition
) for an application to place an icon in the notification area of the Windows UI. 我正在为应用程序开发一个插件(使用
System.ComponentModel.Composition
),以将图标放置在Windows UI的通知区域中。
trayMenu.MenuItems.Clear();
// Create context menu items
foreach( IJob job in jobs ) {
MenuItem menuItem = new MenuItem( job.Name ) {Tag = job};
menuItem.Click += MenuItemClick;
trayMenu.MenuItems.Add( menuItem );
}
private void MenuItemClick( object sender, EventArgs e ) {
// ...
}
Now when I click on an item in the context menu of that icon, the Click
handler is not being invoked. 现在,当我单击该图标的上下文菜单中的某个项目时,不会调用
Click
处理程序。
Interestingly though, when I right-click the icon again (after having clicked a menu item) the Click
handler for the previously clicked MenuItem
is invoked. 但是,有趣的是,当我再次右键单击图标(单击菜单项后)时,将调用先前单击的
MenuItem
的Click
处理程序。 Left-clicking or hovering over the icon does not trigger this step. 左键单击或将鼠标悬停在图标上不会触发此步骤。
What is going on? 到底是怎么回事?
Update : I have a strong feeling my problem is related to this question . 更新 :我很感到我的问题与这个问题有关 。 But I'm still trying to figure out how I could apply that to my plugin/application.
但我仍在尝试弄清楚如何将其应用于我的插件/应用程序。
To my understanding the problem is that no window messages are being processed for the NotifyIcon (or at least not as many messages as I liked/needed). 据我了解,问题在于没有为NotifyIcon处理任何窗口消息(或者至少没有我喜欢/需要的消息数量)。
I solved the issue by inheriting from Form
and running another message pump for my plugin. 我通过从
Form
继承并为插件运行另一个消息泵解决了该问题。
using System;
using ...
namespace JobTracker.Tray {
[Export( typeof( IJobTrackerPlugin ) )]
public class TrayPlugin : Form, IJobTrackerPlugin {
#region Plugin Interface
[Import( typeof( IJobTracker ) )]
#pragma warning disable 649
private IJobTracker _host;
#pragma warning restore 649
private IJobTracker Host {
get { return _host; }
}
public void Initialize() {
trayMenu = new ContextMenu();
trayMenu.MenuItems.Add( "Exit", OnExit );
trayIcon = new NotifyIcon();
trayIcon.Icon = new Icon( SystemIcons.Application, 32, 32 );
trayIcon.ContextMenu = trayMenu;
// Show the proxy form to pump messages
Load += TrayPluginLoad;
Thread t = new Thread(
() => {
ShowInTaskbar = false;
FormBorderStyle = FormBorderStyle.None;
trayIcon.Visible = true;
ShowDialog();
} );
t.Start();
}
private void TrayPluginLoad( object sender, EventArgs e ) {
// Hide the form
Size = new Size( 0, 0 );
}
#endregion
private NotifyIcon trayIcon;
private ContextMenu trayMenu;
private void OnExit( object sender, EventArgs e ) {
Application.Exit();
}
#region Implementation of IDisposable
// ...
private void DisposeObject( bool disposing ) {
if( _disposed ) {
return;
}
if( disposing ) {
// Dispose managed resources.
if( InvokeRequired ) {
EndInvoke( BeginInvoke( new MethodInvoker( Close ) ) );
} else {
Close();
}
trayIcon.Dispose();
trayMenu.Dispose();
}
// Dispose unmanaged resources.
_disposed = true;
}
#endregion
}
}
Seems to work great. 似乎工作很棒。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.