Ken*_*enD 6 .net c# system-tray
我有一个小的C#(.NET 4.0)控制台应用程序,我希望用户能够通过右键单击系统托盘图标时显示菜单来进行交互.我可以在没有任何问题的情况下为托盘添加图标,但我无法显示菜单.我正在使用以下代码:
NotifyIcon trayIcon = new NotifyIcon();
trayIcon.Text = "TestApp";
trayIcon.Icon = new Icon(SystemIcons.Application, 40, 40);
ContextMenu trayMenu = new ContextMenu();
trayMenu.MenuItems.Add("Blah", item1_Click);
trayMenu.MenuItems.Add("Blah2", item1_Click);
trayMenu.MenuItems.Add("Blah3", item1_Click);
trayIcon.ContextMenu = trayMenu;
trayIcon.Visible = true;
Run Code Online (Sandbox Code Playgroud)
...将图标放入托盘中.但是,右键单击该图标不会执行任何操作.我尝试了各种排列MenuItems.Add,但没有任何东西会让菜单出现.我确定我错过了一些简单的东西 - 任何想法是什么?
Rom*_*kov 12
创建图标后尝试添加此项:
Application.Run()
Run Code Online (Sandbox Code Playgroud)
请注意,此方法不会返回,因此在调用之后您无法执行任何操作.这意味着您必须在单独的线程中完成所有其他工作.
操作系统会向您的应用程序发送一条消息,告知它已右键单击托盘图标,但托盘图标代码从未看到它(因为这些消息已被处理Application.Run),因此无法通过打开菜单进行响应.
我只是觉得我会在这里分享......听到有人最终提到Application.Run()是多么幸运.我花了太长时间试图解决这个问题.但是,我想我会分享另一种将所有其他代码放在另一个线程中的替代方法是在主线程以外的线程上创建NotifyIcon,菜单,事件等.这应该包括Application.Run(),因为这允许标准应用程序消息循环在当前线程上工作.然后,由于事件是在同一个线程上创建的,因此Application.Exit()可用于关闭通知消息,但仍允许主线程继续.这是一个控制台应用程序的一个小例子...希望这可以帮助有人想知道他们将如何解决这个问题:
class Program
{
public static ContextMenu menu;
public static MenuItem mnuExit;
public static NotifyIcon notificationIcon;
static void Main(string[] args)
{
Thread notifyThread = new Thread(
delegate()
{
menu = new ContextMenu();
mnuExit = new MenuItem("Exit");
menu.MenuItems.Add(0, mnuExit);
notificationIcon = new NotifyIcon()
{
Icon = Properties.Resources.Services,
ContextMenu = menu,
Text = "Main"
};
mnuExit.Click += new EventHandler(mnuExit_Click);
notificationIcon.Visible = true;
Application.Run();
}
);
notifyThread.Start();
Console.ReadLine();
}
static void mnuExit_Click(object sender, EventArgs e)
{
notificationIcon.Dispose();
Application.Exit();
}
}
Run Code Online (Sandbox Code Playgroud)