winform How to make a Windows Forms.NET application display as tray icon?




winform systray (8)

What needs to be done to have your .NET application show up in Window's system tray as icon?

And how do you handle mousebutton clicks on said icon?


Update C# client whenever database is updated

You probably need to design some kind of poll functionality in your client. For example, you can send a request each minute asking the database "Have you updated anything since [date the client latest got updates]?" If the database answers true, you let the client request the full set of updates. If not, you let it sleep another minute.


My tray icon stops responding when my app is minimized!

Replace f.ShowDialog(); with Application.Run(f); where f is the variable holding your Form and it should work fine. The problem is that ShowDialog returns (and it's message loop ends) when you hide the form. Application.Run provides a proper message loop and your window works after it has been hidden and can be show again using the system tray icon.


Not too sure what your code looks like, but below is some code I pulled from one of our apps. Its written in VB but should not be too hard for you to convert. The key is to create an ApplicationContext class to host your code. This code has no problems showing a form and then closing it repeatedly or with minimizing or maximizing.

Public Class NotifyApplicationContext
Inherits ApplicationContext

Private components As System.ComponentModel.IContainer
Private Notify As System.Windows.Forms.NotifyIcon
Private Menu As System.Windows.Forms.ContextMenu
Private mnuForm As System.Windows.Forms.MenuItem
Private F As Form

Public Sub New()
    InitializeContext()
End Sub

Private Sub InitializeContext()
    Me.components = New System.ComponentModel.Container
    Me.Notify = New System.Windows.Forms.NotifyIcon(Me.components)
    SetupContextMenu()
    Notify.ContextMenu = Me.Menu
    Notify.Icon = New Icon("YourApplicationIcon", 16, 16)
    Notify.Text = "Your Application Text"
    Notify.Visible = True
    F = New Form
    F.Show()
End Sub

Protected Overrides Sub Dispose(ByVal disposing As Boolean)
    MyBase.Dispose(disposing)
End Sub

Protected Overrides Sub ExitThreadCore()
    MyBase.ExitThreadCore()
End Sub

Private Sub SetupContextMenu()
    Me.Menu = New System.Windows.Forms.ContextMenu
    Me.mnuForm = New System.Windows.Forms.MenuItem
    Me.Menu.MenuItems.Add(mnuForm)
    mnuForm.Index = 7
    mnuForm.Text = "FormText"
    AddHandler mnuForm.Click, AddressOf Me.mnuTemp_Click
End Sub

Private Sub mnuForm_Click(ByVal sender As Object, ByVal e As System.EventArgs)
    If F IsNot Nothing Then
        If F.Visible = True Then
            F.Close()
            F.Dispose()
            F = Nothing
        End If
    Else
        F = New Form
        F.Show()
    End If
    Notify.Text = "Change Application Text Here"
End Sub

End Class

Public Class Startup

<STAThread()> _
Public Shared Sub Main()
    Dim N As ApplicationContext = New NotifyApplicationContext
    Application.Run(N)
End Sub

End Class


Quite a long answer, but your best bet would be something like SqlCacheDependency.

Also you could use something called the "Reverse AJAX" technique, which is used by Google Mail notifications, and talked about here: How does incoming mail notification on Gmail works?

Besides those two, your own other options AFAIK is simple server polling.

Also, you haven't mentioned what your client is.

Is it a public web site on the internet? Is it an intranet app, it is a WPF app?

If it's a web site, you're best best is client-side callbacks using the Reverse AJAX technique i mentioned.


C# How to enable form by double clicking on tray icon

Tinkering with the Visible property doesn't work, the Application class forces it on so the form initializes itself properly. You can however override SetVisibleCore() to customize behavior. Paste this code into your form:

bool mLoaded;

protected override void SetVisibleCore(bool value) {
  if (value && !mLoaded) {
    this.CreateHandle();   // Ensure the Load event runs
    value = false;         // Keep invisible
    mLoaded = true;
  }
  base.SetVisibleCore(value);
}

You can add the NotifyIcon component from the toolbox onto your main form.

This has events such as MouseDoubleClick that you can use to handle various events.

Edit: You have to make sure that you set the Icon property to a valid .ico file if you want it to show up properly in the systray.



First, add a NotifyIcon control to the form. Then wire up the Notify Icon to do what you want.

If you want it to hide to tray on minimize, try this.

Private Sub frmMain_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Resize
    If Me.WindowState = FormWindowState.Minimized Then
        Me.ShowInTaskbar = False
    Else
        Me.ShowInTaskbar = True
    End If
End Sub

Private Sub NotifyIcon1_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.MouseClick
    Me.WindowState = FormWindowState.Normal
End Sub

I'll occasionally use the Balloon Text in order to notify a user - that is done as such

 Me.NotifyIcon1.ShowBalloonTip(3000, "This is a notification title!!", "This is notification text.", ToolTipIcon.Info)






systray