With Windows Forms 2.0 and a bit of ingenuity, you can easily make your application minimize to the system tray – that little area to the left of your clock. So let’s see how it’s done…

First stop – the NotifyIcon. The NotifyIcon is a new widget in Windows Forms 2.0, which displays a tray icon for your form. Simply drop a NotifyIcon on your form, set its Icon property to an .ico file of your choice, and set its Visible property to false. (I’m assuming that you want to either display the tray icon or your application, but not both.)

So far, so good. Now we want to find out when the form is minimized. We do this by finding out when the form is resized and examining its current WindowState, which we’ll do by overriding the OnResize method. (Overriding the OnXxx() methods is the preferred method for handling these types of Windows events if you’re creating a derived class since you don’t incur the overhead of a multicast delegate. If you want to capture these events from outside the form, use the appropriate event, such as Resize in our case.) If your WindowsState is minimized, display your tray icon and hide your form.

Now when we double-click our tray icon, we want to reverse the process by hiding the tray icon and displaying the form again. We do this by restoring the previous WindowState, but how do we know what the previous Window state was. We better keep track of it. Whenever a form is minimized, maximized, or restored, OnResize is called (and the Resize event is fired). So as long as the current WindowState isn’t minimized, we squirrel away the current value in a member variable. We then know what to restore the form to when the tray icon is double-clicked. There’s some additional logic in the constructor to set our restore state to a sane value when the application starts up.

That about wraps it up. You can download the sample code MinimizeToTray.zip (22.08 KB), though most is below for your viewing pleasure. Enjoy!

using System;
using System.Windows.Forms;

namespace JamesKovacs.Samples.MinimizeToTray {
public partial class Form1 : Form {
private FormWindowState m_previousWindowState;

public Form1() {
// Store the initial window state that we want to restore to when we double-click the tray icon
m_previousWindowState = (this.WindowState == FormWindowState.Minimized ? FormWindowState.Normal : this.WindowState);

protected override void OnResize(EventArgs e) {
// We need to keep track of whether you’re minimizing from a normal or maximized window
if(this.WindowState != FormWindowState.Minimized) {
= this.WindowState;
= (this.WindowState == FormWindowState.Minimized);
this.Visible = !notifyIcon1.Visible;

private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e) {
this.Visible = true;
= false;
this.WindowState = m_previousWindowState;