如何制作只能在系统托盘中运行的.NET Windows窗体应用程序?
在系统托盘中运行Windows Forms应用程序需要做什么?
不是可以最小化托盘的应用程序,而是仅存在于托盘中的应用程序,只有一个图标,工具提示和“右键单击”菜单。
使用NotifyIcon的基本答案是正确的,但是像.NET的许多事情一样,在做正确的事情时有许多微妙之处。 Brad提到的教程给出了非常基础的一个很好的介绍,但没有解决任何这些问题:
- 从系统托盘中closures应用程序是否能正确closures任何打开的子表单?
- 应用程序是否强制只能运行其中一个实例(适用于大多数,但不是全部的托盘应用程序)?
- 如果需要,如何打开WPF子窗口以及WinForms子窗口。
- 如何支持dynamic上下文菜单。
- WinForms空间中存在标准的NotifyIcon; 我可以做一个纯粹的WPF解决scheme吗? (是的你可以!)
我刚刚在Simple-Talk.com上发表了一篇文章,详细阐述了这些要点,提供了一个可立即使用的托盘应用程序框架,以及一个完整的实际示例应用程序,以便在实践中展示所有内容。 请参阅在.NET中创build托盘应用程序:实用指南 ,2010年11月发布。
代码项目文章创build一个Tasktray应用程序提供了一个非常简单的解释和创build一个只存在于系统托盘的应用程序的例子。
基本上改变Application.Run(new Form1());
在Program.cs
行代替启动一个从ApplicationContext
inheritance的类,并有该类的构造函数初始化一个NotifyIcon
static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MyCustomApplicationContext()); } } public class MyCustomApplicationContext : ApplicationContext { private NotifyIcon trayIcon; public MyCustomApplicationContext () { // Initialize Tray Icon trayIcon = new NotifyIcon() { Icon = Resources.AppIcon, ContextMenu = new ContextMenu(new MenuItem[] { new MenuItem("Exit", Exit) }), Visible = true }; } void Exit(object sender, EventArgs e) { // Hide tray icon, otherwise it will remain shown until user mouses over it trayIcon.Visible = false; Application.Exit(); } }
正如mat1t所说 – 你需要添加一个NotifyIcon到你的应用程序,然后使用类似下面的代码来设置工具提示和上下文菜单:
this.notifyIcon.Text = "This is the tooltip"; this.notifyIcon.ContextMenu = new ContextMenu(); this.notifyIcon.ContextMenu.MenuItems.Add(new MenuItem("Option 1", new EventHandler(handler_method)));
此代码仅在系统托盘中显示图标:
this.notifyIcon.Visible = true; // Shows the notify icon in the system tray
如果您有任何forms的表格(无论什么原因),则需要以下内容:
this.ShowInTaskbar = false; // Removes the application from the taskbar Hide();
右键单击以获取上下文菜单是自动处理的,但是如果您想要在左侧单击某个操作,则需要添加一个Click处理程序:
private void notifyIcon_Click(object sender, EventArgs e) { var eventArgs = e as MouseEventArgs; switch (eventArgs.Button) { // Left click to reactivate case MouseButtons.Left: // Do your stuff break; } }
我用.NET 1.1写了一个traybar应用程序,我不需要表单。
首先,将项目的启动对象设置为模块中定义的Sub Main
。
然后以编程方式创build组件: NotifyIcon
和ContextMenu
。
一定要包含一个MenuItem
“退出”或类似的。
将ContextMenu
绑定到NotifyIcon
。
调用Application.Run()
。
在Quit MenuItem
的事件处理程序中,一定要调用set NotifyIcon.Visible = False
,然后调用Application.Exit()
。 添加你需要的ContextMenu
并正确处理:)
- 使用向导创build一个新的Windows应用程序。
- 从代码中删除
Form1
。 - 删除Program.cs中的代码启动
Form1
。 - 使用
NotifyIcon
类创build系统托盘图标(为其分配一个图标)。 - 添加一个上下文菜单给它。
- 或者对
NotifyIcon
的鼠标点击和鼠标点击做出反应,设置你的上下文菜单并显示哪个button(右/左)被按下。 -
Application.Run()
保持应用程序运行Application.Exit()
退出。 或者一段while(bRunning){Application.DoEvents;Thread.Sleep(10);}
。 然后设置bRunning = false
退出应用程序。
“系统托盘”应用程序只是一个常规的胜利forms的应用程序,唯一不同的是它在Windows系统托盘区域创build一个图标。 为了创buildsys.tray图标使用NotifyIcon组件,您可以在Toolbox(通用控件)中find它,并修改它的属性:图标,工具提示。 它也使您能够处理鼠标点击和双击消息。
还有一件事,为了达到外观和感觉或标准的托盘应用程序。 在主窗体上添加followinf行显示事件:
private void MainForm_Shown(object sender, EventArgs e) { WindowState = FormWindowState.Minimized; Hide(); }
据我所知,你仍然需要使用表单来编写应用程序,但是在表单上没有任何控件,也不能将其设置为可见。 使用NotifyIcon(可以在这里find一个MSDN示例)编写你的应用程序。
这是我用Visual Studio 2010 ,.NET 4做的
- 创build一个Windows窗体应用程序,在属性中设置“使单个实例应用程序”
- 添加一个ContextMenuStrip
- 添加一些条目到上下文菜单条上,双击它们以获得处理程序,例如'exit'(双击) – > handler – > me.Close()
- 添加一个NotifyIcon,在devise器中设置contextMenuStrip到你刚创build的那个,select一个图标(你可以在Visual Studio下的'common7 …'下find一些图标)
- 在devise器中设置表单的属性:FormBorderStyle:none,ShowIcon:false,ShowInTaskbar:false,Opacity:0%,WindowState:Minimized
- 在Form1_Load的末尾添加Me.Visible = false,使用Ctrl + Tab时会隐藏图标
- 根据需要运行和调整。
这是非常友好的通知区域应用程序的框架…它足以将NotificationIcon添加到基础表单并将自动生成的代码更改为以下代码:
public partial class Form1 : Form { private bool hidden = false; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { this.ShowInTaskbar = false; //this.WindowState = FormWindowState.Minimized; this.Hide(); hidden = true; } private void notifyIcon1_Click(object sender, EventArgs e) { if (hidden) // this.WindowState == FormWindowState.Minimized) { // this.WindowState = FormWindowState.Normal; this.Show(); hidden = false; } else { // this.WindowState = FormWindowState.Minimized; this.Hide(); hidden = true; } } }
只需添加
this.WindowState = FormWindowState.Minimized; this.ShowInTaskbar = false;
到你的表单对象。 系统托盘上只会显示一个图标。