본문 바로가기
C#(CSharp)/WPF

Tray Icon running in WPF application

by swconsulting 2015. 3. 17.

WPF Nuget(Open Source)를 이용


1. Nuget 을 이용해서 라이브러리 설치

Hardcodet WPF NotifyIcon 1.0.5


command in the Package Manager Console

PM> Install-Package Hardcodet.NotifyIcon.Wpf


1.1 attach sample code.

http://www.hardcodet.net/wpf-notifyicon [^]


2. Add Resource Dictionary

<App.xaml>

<Application x:Class="SWConsultingStickyNote.App"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" [^]

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" [^]

             ShutdownMode="OnExplicitShutdown"

             >

             <!--Remove startup window because tray icon itself is a startup uri~-->

             <!--StartupUri="MainWindow.xaml">-->

    <Application.Resources>

        <ResourceDictionary>

            <ResourceDictionary.MergedDictionaries>

                <ResourceDictionary Source="/XamlResources/TrayIconResourceDictionary.xaml" />

            </ResourceDictionary.MergedDictionaries>

        </ResourceDictionary>

         

    </Application.Resources>

</Application>


<App.xaml.cs>

using Hardcodet.Wpf.TaskbarNotification;


namespace SWConsultingStickyNote

{

    /// <summary>

    /// Interaction logic for App.xaml

    /// </summary>

    public partial class App : Application

    {

        private TaskbarIcon notifyIcon;


        protected override void OnStartup(StartupEventArgs e)

        {

            base.OnStartup(e);


            //Create notify icon

            notifyIcon = (TaskbarIcon)FindResource("TrayIcon");

        }


        protected override void OnExit(ExitEventArgs e)

        {

            //Clear notify icon resource

            notifyIcon.Dispose();


            base.OnExit(e);

        }

    }

}


<TrayIconResourceDictionary.xaml>

<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:local="clr-namespace:SWConsultingStickyNote.ViewModel.TrayIconVM">

    <!-- Create tray icon context menu -->

    <ContextMenu x:Shared="false" x:Key="SysTrayMenu">

        <MenuItem Header="Show Window" Command="{Binding ShowWindowCommand}" />

        <MenuItem Header="Hide Window" Command="{Binding HideWindowCommand}" />

        <Separator />

        <MenuItem Header="Exit" Command="{Binding ExitApplicationCommand}" />

    </ContextMenu>

    

    <!--Declare tray icon resource-->

    <tb:TaskbarIcon x:Key="TrayIcon"

                    IconSource="/Images/TrayIcon/MainTrayIcon-16x16.ico"

                    ToolTipText="Double-click for main window, right-click for menu"

                    DoubleClickCommand="{Binding ShowWindowCommand}"

                    ContextMenu="{StaticResource ResourceKey=SysTrayMenu}">

        <tb:TaskbarIcon.DataContext>

            <local:TrayIconViewModel /> 

        </tb:TaskbarIcon.DataContext>

        

    </tb:TaskbarIcon>

    

</ResourceDictionary>


3. Add ViewModel


<TrayIconViewModel.cs>

namespace SWConsultingStickyNote.ViewModel.TrayIconVM

{

    public class TrayIconViewModel

    {

        /// <summary>

        /// Shows a window, if none is already open.

        /// </summary>

        public ICommand ShowWindowCommand

        {

            get

            {

                return new DelegateCommand

                {

                    CanExecuteFunc = () => Application.Current.MainWindow == null,

                    CommandAction = () =>

                    {

                        Application.Current.MainWindow = new MainWindow();

                        Application.Current.MainWindow.Show();

                    }

                };

            }

        }


        /// <summary>

        /// Hides the main window. This command is only enabled if a window is open.

        /// </summary>

        public ICommand HideWindowCommand

        {

            get

            {

                return new DelegateCommand

                {

                    CommandAction = () => Application.Current.MainWindow.Close(),

                    CanExecuteFunc = () => Application.Current.MainWindow != null

                };

            }

        }



        /// <summary>

        /// Shuts down the application.

        /// </summary>

        public ICommand ExitApplicationCommand

        {

            get

            {

                return new DelegateCommand {CommandAction = () => Application.Current.Shutdown()};

            }

        }

    }


}


<DelegateCommand.cs>

using System;

using System.Windows.Input;


namespace SWConsultingStickyNote.ViewModel.TrayIconVM

{

    /// <summary>

    /// Simplistic delegate command for tray menu action.

    /// </summary>

    public class DelegateCommand : ICommand

    {

        public Action CommandAction { get; set; }


        public Func<bool> CanExecuteFunc { get; set; }


        public void Execute(object parameter)

        {

            CommandAction();

        }


        public bool CanExecute(object parameter)

        {

            return CanExecuteFunc == null || CanExecuteFunc();

        }


        public event EventHandler CanExecuteChanged

        {

            add

            {

                CommandManager.RequerySuggested += value;

            }

            remove

            {

                CommandManager.RequerySuggested -= value;

            }

        }

    }

}


4. Add Tray Icon Image