Skip to content

Repository files navigation

Tray Icon

Library that allows use Tray Icon in WPF Application. Ported from Windows Forms. Has wrapper for WPF ContexMenu (which converts it to Windows Forms ContextMenu). This is needed for good performance, and compatibility. This library targets all MVVM requirements:

  • it has bindable properties
  • it has interface with notify methods

Getting started.

Use one of the follwing methods to install and use this library:

  • Package Manager:

    PM> Install-Package TrayIcon
  • .NET CLI:

    > dotnet add package TrayIcon

First you need to include namespace to your code or markup.

For XAML it can look like:

<Windowxmlns:icon="https://github.com/nullsoftware/TrayIcon" />

And for C#:

usingNullSoftware.ToolKit;

Then you can place tray icon inside your window, or keep it in variable/property.

For XAML:

<icon:TrayIconHandlers.TrayIcons>
<icon:TrayIconTitle="My Application"IconSource="MainIcon.ico"ClickCommand="{Binding ExampleCommand}"NotificationServiceMemberPath="NotificationService"/>
</icon:TrayIconHandlers.TrayIcons>

For C#:

TrayIconmyTrayIcon=newTrayIcon(){Title="My Application",IconSource=newBitmapImage(newUri("pack://application:,,,/MainIcon.ico")),ClickCommand=newRelayCommand(ExampleAction)};

To show balloon you need to call Notify method:

INotificationServicenotifyService=myTrayIcon;notifyService.Notify("Greetings","Hello World!",NotificationType.Information);

Note:INotificationService can be obtained from XAML by using NotificationServiceMemberPath. It injects INotificationService to specified DataContext property.

Backward compatibility

To support latest .NET versions was added ContextMenuVariation property to TrayIcon.
It allows to switch beetwen System.Windows.Forms.ContextMenu or System.Windows.Forms.ContextMenuStrip.
Warning: .NET Core 3.1 and later versions don't support System.Windows.Forms.ContextMenu. See more at the documentation page.

Dynamic context menu items

Any MenuItem (or the root ContextMenu) can have its children built from an ObservableCollection<MenuItem> bound through ItemsSource. Adds, removes, replaces, moves and Clear() (Reset) are forwarded to the underlying tray menu — no need to rebuild the menu manually.

XAML:

<MenuItemHeader="Recent Files"ItemsSource="{Binding RecentFiles}"/>

ViewModel:

publicObservableCollection<MenuItem>RecentFiles{get;}=newObservableCollection<MenuItem>();privatevoidRegisterRecent(stringpath){RecentFiles.Add(newMenuItem{Header=path,Command=newRelayCommand(()=>Process.Start(path)),});}

The items in the bound collection must be System.Windows.Controls.MenuItem (or Separator) instances. Direct mutation of MenuItem.Items from code-behind is also supported.

Menu item icons

WPF MenuItem.Icon is forwarded to ToolStripMenuItem.Image automatically. Both static and bound icons are supported, and changes update live.

<MenuItemHeader="Open">
<MenuItem.Icon>
<ImageSource="open.png"/>
</MenuItem.Icon>
</MenuItem>

Accepted Icon values: a BitmapSource, an Image element with any ImageSource (the typical XAML form above), or any other ImageSource such as DrawingImage — non-bitmap sources are rendered to a 16×16 PNG.

Warning: icons are only rendered when ContextMenuVariation is ContextMenuStrip (the default on .NET Core 3.0+). The legacy System.Windows.Forms.MenuItem used by ContextMenuVariation.ContextMenu has no icon property.

Full Example

<Windowx:Class="TrayIcon.Example.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:TrayIcon.Example"xmlns:vm="clr-namespace:TrayIcon.Example.ViewModels"xmlns:icon="https://github.com/nullsoftware/TrayIcon"mc:Ignorable="d"Title="MainWindow"Height="450"Width="800"Icon="MainIcon.ico">
<Window.DataContext>
<vm:MainViewModel/>
</Window.DataContext>
<!--Here you can place your icons-->
<icon:TrayIconHandlers.TrayIcons>
<icon:TrayIconTitle="My Application"IconSource="MainIcon.ico"DoubleClickCommand="{Binding MinimazeCommand}"NotificationServiceMemberPath="NotificationService">
<icon:TrayIcon.ContextMenu>
<!--This context menu will be converted to System.Windows.Forms.ContextMenu-->
<ContextMenu>
<MenuItemHeader="Notify"Command="{Binding SayHelloCommand}" icon:TrayIcon.IsDefault="True"/>
<Separator/>
<MenuItemHeader="_Silent Mode"IsCheckable="True"IsChecked="{Binding IsSilentModeEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Separator/>
<MenuItemHeader="E_xit"Command="{Binding CloseCommand}"/>
</ContextMenu>
</icon:TrayIcon.ContextMenu>
</icon:TrayIcon>
</icon:TrayIconHandlers.TrayIcons>
<Grid>
<StackPanelVerticalAlignment="Top"HorizontalAlignment="Left"Margin="10, 20"Orientation="Horizontal">
<CheckBoxVerticalAlignment="Center"IsChecked="{Binding IsSilentModeEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"Content="Silent Mode"/>
<ButtonMargin="20, 0, 0, 0"Padding="10, 3"MinWidth="86"Command="{Binding SayHelloCommand}"Content="Notify"/>
</StackPanel>
</Grid>
</Window>

ViewModel:

usingSystem;usingSystem.Windows.Input;usingNullSoftware.ToolKit;usingPropertyChanged;publicclassMainViewModel:ObservableObject{publicboolIsSilentModeEnabled{get;set;}[DoNotNotify]publicICommandMinimazeCommand{get;}[DoNotNotify]publicICommandSayHelloCommand{get;}[DoNotNotify]publicICommandCloseCommand{get;}[DoNotNotify]privateINotificationServiceNotificationService{get;set;}publicMainViewModel(){MinimazeCommand=newRelayCommand(()=>App.Current.MainWindow.WindowState=System.Windows.WindowState.Minimized);SayHelloCommand=newRelayCommand(()=>NotificationService.Notify("Greetings","Hello World!"));CloseCommand=newRelayCommand(App.Current.MainWindow.Close);}}

Note: in ViewModel was used PropertyChanged.Fody plugin, to simplify usage of INotifyPropertyChanged.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Credits

Developed by Null Software

Repository

https://github.com/nullsoftware/TrayIcon

About

Tray Icon for WPF Application. Has wrapper for WPF ContexMenu.

Topics

Resources

Stars

22 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages