如何制作只能在系统托盘中运行的.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行代替启动一个从ApplicationContextinheritance的类,并有该类的构造函数初始化一个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组件: NotifyIconContextMenu
一定要包含一个MenuItem “退出”或类似的。
ContextMenu绑定到NotifyIcon
调用Application.Run()
在Quit MenuItem的事件处理程序中,一定要调用set NotifyIcon.Visible = False ,然后调用Application.Exit() 。 添加你需要的ContextMenu并正确处理:)

  1. 使用向导创build一个新的Windows应用程序。
  2. 从代码中删除Form1
  3. 删除Program.cs中的代码启动Form1
  4. 使用NotifyIcon类创build系统托盘图标(为其分配一个图标)。
  5. 添加一个上下文菜单给它。
  6. 或者对NotifyIcon的鼠标点击和鼠标点击做出反应,设置你的上下文菜单并显示哪个button(右/左)被按下。
  7. 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做的

  1. 创build一个Windows窗体应用程序,在属性中设置“使单个实例应用程序”
  2. 添加一个ContextMenuStrip
  3. 添加一些条目到上下文菜单条上,双击它们以获得处理程序,例如'exit'(双击) – > handler – > me.Close()
  4. 添加一个NotifyIcon,在devise器中设置contextMenuStrip到你刚创build的那个,select一个图标(你可以在Visual Studio下的'common7 …'下find一些图标)
  5. 在devise器中设置表单的属性:FormBorderStyle:none,ShowIcon:false,ShowInTaskbar:false,Opacity:0%,WindowState:Minimized
  6. 在Form1_Load的末尾添加Me.Visible = false,使用Ctrl + Tab时会隐藏图标
  7. 根据需要运行和调整。

这是非常友好的通知区域应用程序的框架…它足以将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; 

到你的表单对象。 系统托盘上只会显示一个图标。