Click here to Skip to main content
15,896,429 members
Articles / Desktop Programming / WPF

WPF NotifyIcon

Rate me:
Please Sign up or sign in to vote.
4.98/5 (483 votes)
23 Nov 2013CPOL16 min read 1.8M   48.6K   704  
A NotifyIcon for WPF that leverages several features of the platform
<Window
    x:Class="Samples.ShowcaseWindow"
    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:sys="clr-namespace:System;assembly=mscorlib"
    Title="WPF NotifyIcon"
    Height="874"
    Width="936.387"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:local="clr-namespace:Samples"
    xmlns:Commands="clr-namespace:Samples.Commands"
    MinWidth="750"
    MinHeight="800"
    ResizeMode="NoResize">
    <Window.Resources>

        <BooleanToVisibilityConverter
            x:Key="BooleanToVisibilityConverter" />

        <ObjectDataProvider
            MethodName="GetValues"
            ObjectType="{x:Type sys:Enum}"
            x:Key="ActivationModes">
            <ObjectDataProvider.MethodParameters>
                <x:Type
                    TypeName="tb:PopupActivationMode" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>

    </Window.Resources>
    <Window.Background>
        <LinearGradientBrush
            EndPoint="0.771,0.907"
            StartPoint="0.229,0.093">
            <GradientStop
                Color="#FFFFFFFF"
                Offset="1" />
            <GradientStop
                Color="#FFDAE9FF" />
        </LinearGradientBrush>
    </Window.Background>
    <Window.Triggers>
        <EventTrigger
            RoutedEvent="tb:TaskbarIcon.TrayToolTipOpen"
            SourceName="tb" />
    </Window.Triggers>

    <Grid
        Hyperlink.RequestNavigate="OnNavigationRequest">


        <!--
      THE TASKBARICON ELEMENT WAS DECLARED INLINE IN ORDER TO USE DATABINDING
      FOR ITS PROPERTIES. IN  A REAL-LIFE APP, YOU'D PROBABLY RATHER DECLARE
      IT IN A RESOURCE DICTIONARY SO YOU CAN ALSO USE IT IF THERE IS NO WINDOW
      OPEN.
    -->

        <tb:TaskbarIcon
            x:Name="tb"
            VerticalAlignment="Top"
            IconSource="{Binding Path=SelectedItem.Source, ElementName=iconList, Mode=Default}"
            ContextMenu="{StaticResource tbMenu}"
            ToolTipText="{Binding Path=Text, ElementName=txtToolTipText, Mode=Default}"
            Visibility="{Binding Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=iconVisibility, Mode=Default}"
            MenuActivation="{Binding Path=SelectedItem, ElementName=lstMenuTrigger, Mode=Default}"
            PopupActivation="{Binding Path=SelectedItem, ElementName=lstPopupTrigger, Mode=Default}"
            DoubleClickCommand="{Commands:ShowSampleWindowCommand}"
            DoubleClickCommandParameter="{Binding RelativeSource={RelativeSource Self}}">

            <tb:TaskbarIcon.TrayPopup>
                <!-- the control will be put into a popup with an explicit DataContext -->
                <local:FancyPopup />
            </tb:TaskbarIcon.TrayPopup>

            <tb:TaskbarIcon.TrayToolTip>
                <!-- the control will be put into a tooltip with an explicit DataContext -->
                <local:FancyToolTip
                    Opacity="0.85"
                    InfoText="{Binding Path=ToolTipText}" />
            </tb:TaskbarIcon.TrayToolTip>

        </tb:TaskbarIcon>


        <!-- ************************************************************************************* -->
        <!-- ************************************************************************************* -->
        <!-- EVERYTHING BELOW IS JUST PLUMBING FOR THE SAMPLE -->


        <Grid
            Margin="509.567,578.58,0,0"
            VerticalAlignment="Top"
            Height="248"
            x:Name="Balloons"
            Width="405.32"
            HorizontalAlignment="Left">
            <Border
                HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                BorderBrush="Black"
                BorderThickness="2,2,2,2" />
            <TextBox
                Margin="125,0,17,133"
                x:Name="txtBalloonTitle"
                VerticalAlignment="Bottom"
                Height="23">
                WPF NotifyIcon
            </TextBox>
            <TextBox
                Margin="125,0,17,76"
                x:Name="txtBalloonText"
                AcceptsReturn="True"
                Height="47"
                VerticalAlignment="Bottom"
                d:LayoutOverrides="VerticalAlignment"
                TextWrapping="Wrap"
                Text="You should see a LED icon in your system tray. This is your NotifyIcon." />
            <RadioButton
                HorizontalAlignment="Left"
                Margin="14,0,0,54"
                VerticalAlignment="Bottom"
                Width="111"
                Height="22"
                Content="Show as Info"
                IsChecked="True"
                x:Name="rbInfo" />
            <TextBlock
                HorizontalAlignment="Left"
                Margin="14,0,0,133"
                VerticalAlignment="Bottom"
                Width="85"
                Height="23"
                TextWrapping="Wrap">
                <Run
                    Text="Balloon Title" />
            </TextBlock>
            <TextBlock
                Margin="14,0,0,100"
                TextWrapping="Wrap"
                HorizontalAlignment="Left"
                Width="85"
                Height="23"
                VerticalAlignment="Bottom"
                d:LayoutOverrides="VerticalAlignment">
                <Run
                    Text="Balloon Text" />
            </TextBlock>
            <RadioButton
                Margin="14,0,0,32"
                VerticalAlignment="Bottom"
                Height="22"
                Content="Show as Error"
                HorizontalAlignment="Left"
                Width="111"
                x:Name="rbError" />
            <RadioButton
                Margin="14,0,0,10"
                VerticalAlignment="Bottom"
                Height="22"
                Content="Show Custom Icon"
                HorizontalAlignment="Left"
                Width="130"
                x:Name="rbCustomIcon" />
            <Button
                HorizontalAlignment="Right"
                Margin="0,0,17,43"
                x:Name="showBalloonTip"
                Width="120"
                Content="Show Balloon Tip"
                VerticalAlignment="Bottom"
                Height="23"
                Click="showBalloonTip_Click" />
            <TextBlock
                Margin="10,35.96,21,0"
                VerticalAlignment="Top"
                Height="56.04"
                TextWrapping="Wrap">
                <Run
                    Text="Displays default balloon tips as supported by the OS. " />
                <Run
                    Text="You can use custom icons under all OS versions" />
                <Run
                    Text=" (not supported by WinForms NotifyIcon)." />
                <Run
                    Text="." />
            </TextBlock>
            <Button
                HorizontalAlignment="Right"
                Margin="0,0,17,12.52"
                x:Name="hideBalloonTip"
                Width="120"
                Content="Hide Balloon Tip"
                VerticalAlignment="Bottom"
                Height="23"
                Click="hideBalloonTip_Click" />
            <TextBlock
                HorizontalAlignment="Left"
                Margin="10,10,0,0"
                VerticalAlignment="Top"
                Width="Auto"
                Height="Auto"
                FontWeight="Bold"
                TextDecorations="Underline"
                TextWrapping="Wrap">
                <Run
                    Text="Standard (OS) Balloon Tips" />
            </TextBlock>
        </Grid>
        <Grid
            HorizontalAlignment="Left"
            Margin="12,543.88,0,0"
            VerticalAlignment="Top"
            Width="469.5"
            Height="282.7"
            x:Name="Popups">
            <Border
                HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                BorderBrush="#FF000000"
                BorderThickness="2,2,2,2" />
            <ListBox
                IsSynchronizedWithCurrentItem="False"
                x:Name="lstPopupTrigger"
                ItemsSource="{Binding Mode=OneWay, Source={StaticResource ActivationModes}}"
                Margin="10,0,190,10"
                SelectedIndex="0"
                Height="117"
                VerticalAlignment="Bottom" />
            <TextBlock
                Margin="10,31.7,14,137"
                TextWrapping="Wrap">
                <Run
                    Text="If the user clicks on the " />
                <Run
                    Text="Notify" />
                <Run
                    Text="Icon, a " />
                <Run
                    Text="P" />
                <Run
                    Text="opup can be opened and displayed" />
                <Run
                    Text=" that allows the user to quickly interact with the application" />
                <Run
                    Text=". " />
                <Run
                    Text="Unlike custom ToolTips, this works under all OS versions" />
                <Run
                    Text=". " />
                <Run
                    Text="Which mouse button(s) opens the Popup is " />
                <Run
                    Text="determined by the " />
                <Run
                    FontStyle="Italic"
                    FontWeight="Bold"
                    Text="PopupActivation " />
                <Run
                    Text="property." />
                <Run
                    Text=" If both Popup and ContextMenu are configured for the same mouse buttons, ContextMenu takes precedence." />
                <LineBreak />
                <Run
                    Text="(Note: " />
                <Run
                    Text="In case left-clicks are used, popups are displayed with a delay to ensure the user does not double-click." />
                <Run
                    Text=")" />
            </TextBlock>
            <TextBlock
                HorizontalAlignment="Left"
                Margin="10,10,0,0"
                VerticalAlignment="Top"
                Width="Auto"
                Height="Auto"
                FontWeight="Bold"
                TextDecorations="Underline"
                TextWrapping="Wrap">
                <Run
                    Text="Popup Controls" />
            </TextBlock>
        </Grid>
        <Grid
            Margin="10,278,0,0"
            x:Name="ToolTips"
            Height="255.88"
            VerticalAlignment="Top"
            Width="471.5"
            HorizontalAlignment="Left">
            <Border
                HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                BorderBrush="#FF000000"
                BorderThickness="2,2,2,2" />
            <TextBox
                Margin="10,0,25,60"
                x:Name="txtToolTipText"
                VerticalAlignment="Bottom"
                Height="23"
                Text="THIS IS A SAMPLE TEXT...."
                Foreground="#FFFF0000" />
            <TextBlock
                Margin="10,0,25,93"
                TextWrapping="Wrap"
                Height="21"
                VerticalAlignment="Bottom">
                <Run
                    Text="ToolTipText" />
                <Run
                    Text=" (assigned to property and also used by several bindings)" />
                <Run
                    Text=":" />
            </TextBlock>
            <TextBlock
                Margin="10,29.88,10,114"
                TextWrapping="Wrap">
                <Run
                    Text="If the user moves the mouse over the " />
                <Run
                    Text="Notify" />
                <Run
                    Text="Icon, " />
                <Run
                    Text="a ToolTip " />
                <Run
                    Text="can be displayed. Starting from Windows Vista, we have convenient events to display and hide tooltips." />
                <Run
                    Text=" You can assign arbitrary UIElements (e.g. User Controls) to the " />
                <Run
                    FontStyle="Italic"
                    FontWeight="Bold"
                    Text="TrayToolTip " />
                <Run
                    Text="property." />
                <LineBreak />
                <Run
                    Text="" />
                <Run
                    Text="If " />
                <Run
                    FontStyle="Italic"
                    FontWeight="Bold"
                    Text="TrayToolTip " />
                <Run
                    Text="is not set or the app runs under an older OS (e.g. " />
                <Run
                    Text="Windows " />
                <Run
                    Text="xp), the " />
                <Run
                    Text="NotifyIcon " />
                <Run
                    Text="falls back to the " />
                <Run
                    FontStyle="Italic"
                    FontWeight="Bold"
                    Text="ToolTipText " />
                <Run
                    Text="property." />
            </TextBlock>
            <Button
                HorizontalAlignment="Left"
                Margin="10,0,0,10"
                VerticalAlignment="Bottom"
                Width="147"
                Height="24"
                Content="Remove Custom ToolTip"
                Name="removeToolTip"
                Click="removeToolTip_Click" />
            <TextBlock
                Margin="10,0,25,44"
                VerticalAlignment="Bottom"
                Height="16"
                TextWrapping="Wrap">
                <Run
                    Text="Click to fall back to ToolTipText (sets TrayToolTip to null):" />
            </TextBlock>
            <TextBlock
                HorizontalAlignment="Left"
                Margin="10,10,0,0"
                VerticalAlignment="Top"
                Width="Auto"
                Height="Auto"
                FontWeight="Bold"
                TextDecorations="Underline"
                TextWrapping="Wrap">
                <Run
                    Text="ToolTips and ToolTipText" />
            </TextBlock>
        </Grid>
        <Grid
            HorizontalAlignment="Left"
            Margin="509.567,114.5,0,0"
            Width="405.32"
            x:Name="ContextMenus"
            Height="255.88"
            VerticalAlignment="Top">
            <Border
                BorderBrush="#FF000000"
                BorderThickness="2,2,2,2" />
            <ListBox
                Margin="10,0,95,10"
                IsSynchronizedWithCurrentItem="False"
                x:Name="lstMenuTrigger"
                ItemsSource="{Binding Mode=OneWay, Source={StaticResource ActivationModes}}"
                Height="124"
                VerticalAlignment="Bottom"
                SelectedIndex="1" />
            <TextBlock
                Margin="10,97,48,0"
                VerticalAlignment="Top"
                Height="22"
                TextWrapping="Wrap">
                <Run
                    Text="Mouse events that open the context menu:" />
            </TextBlock>
            <TextBlock
                Margin="10,30,10,0"
                VerticalAlignment="Top"
                Height="57"
                TextWrapping="Wrap">
                <Run
                    Text="Assign a custon context menu through the " />
                <Run
                    FontStyle="Italic"
                    FontWeight="Bold"
                    Text="ContextMenu " />
                <Run
                    Text="property of the " />
                <Run
                    Text="Notify" />
                <Run
                    Text="Icon. The " />
                <Run
                    FontStyle="Italic"
                    FontWeight="Bold"
                    Text="MenuActivation " />
                <Run
                    Text="property determines what mouse events open the context menu." />
            </TextBlock>
            <TextBlock
                Margin="10,10,0,0"
                VerticalAlignment="Top"
                Height="Auto"
                TextWrapping="Wrap"
                Width="Auto"
                HorizontalAlignment="Left"
                FontWeight="Bold"
                TextDecorations="Underline">
                <Run
                    Text="Context Menu" />
            </TextBlock>
        </Grid>
        <TextBlock
            Margin="10,10,0,0"
            VerticalAlignment="Top"
            Height="Auto"
            TextWrapping="Wrap"
            FontWeight="Bold"
            FontSize="16"
            HorizontalAlignment="Left">
            <Run
                Text="WPF NotifyIcon" />
        </TextBlock>
        <TextBlock
            Margin="12,57.62,15.5,0"
            VerticalAlignment="Top"
            FontSize="14"
            FontStyle="Italic"
            Foreground="#FF303030"
            TextWrapping="Wrap"
            HorizontalAlignment="Stretch">
            <Run
                Text="This " />
            <Run
                Text="is a showcase of the different features of the WPF NotifyIcon. Have a look at the used controls and styles in order to see how binding can be supported. For a real-life " />
            <Run
                Text="example" />
            <Run
                Text=", " />
            <Run
                Language="de-ch"
                Text="check out " />
            <Hyperlink
                NavigateUri="http://www.hardcodet.net/netdrives/">
                <Run
                    Text="NetDrives" />
            </Hyperlink>
        </TextBlock>
        <Grid
            Margin="509.567,380.38,0,0"
            x:Name="CustomBalloons"
            Height="188.2"
            VerticalAlignment="Top"
            Width="405.32"
            HorizontalAlignment="Left">
            <Border
                HorizontalAlignment="Stretch"
                Width="Auto"
                BorderThickness="2,2,2,2"
                BorderBrush="#FF000000" />
            <Button
                Content="Show"
                x:Name="showCustomBalloon"
                Click="showCustomBalloon_Click"
                HorizontalAlignment="Right"
                Margin="0,0,91.377,10"
                Width="71.623"
                Height="23"
                VerticalAlignment="Bottom" />
            <TextBox
                VerticalAlignment="Bottom"
                Height="23"
                Text="WPF Balloon"
                TextWrapping="Wrap"
                Margin="10,0,173,10"
                x:Name="customBalloonTitle" />
            <TextBlock
                Margin="10,35,24.377,0"
                VerticalAlignment="Top"
                TextWrapping="Wrap"
                Height="119.68">
                <Run
                    Text="Custom " />
                <Run
                    Text="Balloons are much " />
                <Run
                    Text="ore flexible then standard balloons " />
                <Run
                    Text="tips " />
                <Run
                    Text="when it comes to styling." />
                <Run
                    Text=" You can display arbitrary UI Elements (e.g. User Controls) as custom balloons." />
                <LineBreak />
                <Run
                    Text="Apart from the richer UI, custom balloons also provide a" />
                <Run
                    Text="ttached properties and events that can be used to control behavior." />
                <Run
                    Text=" Custom balloons also work if the NotifyIcon is not visible." />
                <LineBreak />
                <Run
                    Text="(Hint: Hover over the " />
                <Run
                    Text="balloon " />
                <Run
                    Text="to suspend the fade-out.)" />
            </TextBlock>
            <Button
                Content="Close"
                x:Name="hideCustomBalloon"
                Click="hideCustomBalloon_Click"
                HorizontalAlignment="Right"
                Margin="0,0,9.754,10.52"
                Width="71.623"
                Height="23"
                VerticalAlignment="Bottom" />
            <TextBlock
                HorizontalAlignment="Left"
                Margin="10,10,0,0"
                VerticalAlignment="Top"
                Width="Auto"
                Height="Auto"
                FontWeight="Bold"
                TextDecorations="Underline"
                TextWrapping="Wrap">
                <Run
                    Text="Custom Balloons" />
            </TextBlock>
        </Grid>
        <Grid
            Margin="10,114.5,0,0"
            VerticalAlignment="Top"
            Height="147.351"
            x:Name="Common"
            Width="471.5"
            HorizontalAlignment="Left">
            <Border
                BorderThickness="2,2,2,2"
                BorderBrush="#FF000000"
                d:IsLocked="True" />
            <CheckBox
                Margin="10,35.96,0,0"
                VerticalAlignment="Top"
                Content="NotifyIcon Visible"
                x:Name="iconVisibility"
                IsChecked="True"
                HorizontalAlignment="Left"
                Width="155.42"
                d:LayoutOverrides="Height" />
            <ListBox
                Margin="10,77.38,0,0"
                IsSynchronizedWithCurrentItem="True"
                x:Name="iconList"
                SelectedIndex="0"
                Width="123"
                HorizontalAlignment="Left"
                Height="59.971"
                VerticalAlignment="Top" ScrollViewer.VerticalScrollBarVisibility="Auto">
                <Image
                    Width="16"
                    Margin="0,4,0,0"
                    Height="16"
                    Source="/Icons/Inactive.ico" />
                <Image
                    Width="16"
                    Margin="0,4,0,0"
                    Height="16"
                    Source="/Icons/Error.ico" />

            </ListBox>
            <TextBlock
                Margin="10,55.38,0,61"
                Width="Auto"
                TextWrapping="Wrap"
                d:LayoutOverrides="Width"
                HorizontalAlignment="Left">
                <Run
                    Text="Select an image to switch icons:" />
            </TextBlock>
            <TextBlock
                HorizontalAlignment="Left"
                Margin="10,10,0,0"
                VerticalAlignment="Top"
                Width="Auto"
                Height="Auto"
                FontWeight="Bold"
                TextDecorations="Underline"
                TextWrapping="Wrap">
                <Run
                    Text="Icon / Visibility" />
            </TextBlock>
        </Grid>
    </Grid>
</Window>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect I'm a gun for hire
Switzerland Switzerland
Philipp is an independent software engineer with great love for all things .NET.
He lives in Winterthur, Switzerland and his home on the web is at http://www.hardcodet.net.

Comments and Discussions