Systemtray Icon

WPF has no built in Systemtray or Notify Icon like WinForm does. If you want to have this for your app, you could use wpf-notifyicon from hardcodet.

I use this from my Winsomnia and StandUpMate projects, too.

StandUpMate Systemtray Icon

Setup

Create a ressource dictionary in the App.xaml file:

StandUpMate Systemtray Icon

1
2
3
4
5
6
7
8
9
10
11
12
13
<Application x:Class="StandUpMate.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:StandUpMate"
             ShutdownMode="OnExplicitShutdown">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resource/NotifyIconResources.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Change the ShutdownMode to ShutdownMode="OnExplicitShutdown" to control the app via context menu of your systemtray icon.

Example for the Resource/NotifyIconResources.xaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:tb="http://www.hardcodet.net/taskbar"
                    xmlns:vm="clr-namespace:StandUpMate.ViewModel">

    <ContextMenu x:Shared="false" x:Key="SysTrayMenu">
        <MenuItem Header="Start timer" Command="{Binding StartTimerCommand}" />
        <MenuItem Header="Stop timer" Command="{Binding StopTimerCommand}" />
        <MenuItem Header="Show remaining time" Command="{Binding ShowRemainingTimeCommand}" />
        <Separator />
        <MenuItem Header="Settings" Command="{Binding ShowSettingsWindowCommand}" />
        <MenuItem Header="Close" Command="{Binding ExitApplicationCommand}" />
    </ContextMenu>

    <tb:TaskbarIcon x:Key="NotifyIcon"
                    IconSource="/Resource/clock.ico"
                    ToolTipText="StandUpMate"
                    LeftClickCommand="{Binding LeftClickCommand}"
                    DoubleClickCommand="{Binding ShowSettingsWindowCommand}"
                    ContextMenu="{StaticResource SysTrayMenu}">

        <tb:TaskbarIcon.DataContext>
            <vm:NotifyIconViewModel />
        </tb:TaskbarIcon.DataContext>
    </tb:TaskbarIcon>
</ResourceDictionary>

The context menu is defined between the <ContextMenu> tags with a <Separator /> and some commands. The icon can be referenced in the tb:TaskbarIcon> tag, alongside the dataContext and further commands for UI control.

Changing Icon on events, e.g. click

If you want to have a changing icon for certain events, e.g. grey icon for a deactivated mode and green icon for activated mode, you can look at my Winsomnia project, where I have implemented exactly that.

With the class NotifyIcon I have built the base for accessing and initializing the NotifyIcon on app startup:

1
2
3
4
5
6
7
8
9
using Hardcodet.Wpf.TaskbarNotification;

namespace Winsomnia.Utility
{
    public static class NotifyIcon
    {
        public static TaskbarIcon TrayIcon;
    }
}

This is used in the App.xaml.cs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using Hardcodet.Wpf.TaskbarNotification;
using System.Windows;
using Winsomnia.Utility;
using Winsomnia.ViewModel;

namespace Winsomnia
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            NotifyIcon.TrayIcon = (TaskbarIcon)FindResource("NotifyIcon");

            var notifyIconVM = new NotifyIconViewModel();
            NotifyIcon.TrayIcon.DataContext = notifyIconVM;

            if (Winsomnia.Properties.Settings.Default.ActivateOnStart)
                notifyIconVM.SwitchMode();
        }

        protected override void OnExit(ExitEventArgs e)
        {
            NotifyIcon.TrayIcon.Dispose();
            base.OnExit(e);
        }
    }
}

The ressource for it is a bit smaller than the example on the top of the article:

1
2
3
4
5
6
7
<tb:TaskbarIcon x:Key="NotifyIcon"
    IconSource="/Resource/Default.ico"
    ToolTipText="Winsomnia"
    LeftClickCommand="{Binding SwitchModeCommand}"
    DoubleClickCommand="{Binding SwitchModeCommand}"
    ContextMenu="{StaticResource SysTrayMenu}">
</tb:TaskbarIcon>

The switch of the system mode should also switch the icon, either with a call from the LeftClickCommand or context menu, or else. This can be achieved with accessing the NotifyIcon in the ViewModel and replace the defined icon with another one:

StandUpMate Systemtray Icon