The Windows 7 taskbar is more than just a place to hold icons for running and pinned applications. Among other things, you can use it to display the progress of a long-running operation and overlay informational icons to indicate a change in application state – the topic of this post.
Uses
Taskbar overlays can be used to show information to the user that is not critical in nature, but which may be interesting to them. For example, Outlook 2010 adds an envelope overlay when new mail arrives.
Fishbowl, the Facebook application for Windows, uses it to indicate how many new items have arrived.
Your own applications may want to use it to indicate new tasks in a queue, what long-running operation is being performed (when used along with the progress reporting), what screen the application is on (to help differentiate from other instances of the same application) etc.
Project Setup
Create a regular WPF 4 Windows application using Visual Studio 2010, and open up the xaml for the main window. I called my application WpfTaskbarIconOverlay.
Main Window
The main Window has two buttons and the TaskbarItemInfo declaration
<Window x:Class="WpfTaskbarIconOverlay.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF Taskbar Overlay Window"
Height="350"
Width="525">
<Window.TaskbarItemInfo>
<TaskbarItemInfo />
</Window.TaskbarItemInfo>
<Grid>
<StackPanel Width="120"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Button x:Name="AddOverlay"
Content="Add Overlay"
Margin="10" />
<Button x:Name="RemoveOverlay"
Content="Remove Overlay"
Margin="10" />
</StackPanel>
</Grid>
</Window>
The end result should look like this:
In the code-behind, wire up event handlers for the two buttons
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
AddOverlay.Click += new RoutedEventHandler(AddOverlay_Click);
RemoveOverlay.Click += new RoutedEventHandler(RemoveOverlay_Click);
}
void RemoveOverlay_Click(object sender, RoutedEventArgs e)
{
}
void AddOverlay_Click(object sender, RoutedEventArgs e)
{
}
}
Setting up the Overlay Images
The TaskbarItemInfo.Overlay property is of type ImageSource, so anything that can be represented as such may be used as an overlay. That includes both vector and bitmap content.
You can create the content in code, or, like most things in WPF, represent it in Xaml as a resource. We’ll add just a little more markup and code here to get the resources in place.
First, we’ll create the window resources in xaml. We won’t actually draw anything yet, just set up the resource. The Window.Resources section is a child of the Window, and is typically placed right after the <Window …> opening tag.
<Window.Resources>
<DrawingImage x:Key="OverlayImage">
</DrawingImage>
</Window.Resources>
Here’s the updated set of event handlers in the code-behind. Note that the AddOverlay button simply assigns the overlay from the resources, and the RemoveOverlay button nulls out the Overlay image.
void RemoveOverlay_Click(object sender, RoutedEventArgs e)
{
TaskbarItemInfo.Overlay = null;
}
void AddOverlay_Click(object sender, RoutedEventArgs e)
{
TaskbarItemInfo.Overlay = (ImageSource)Resources["OverlayImage"];
}
Next, we’ll overlay a couple types of image.
Overlaying Vector Drawings
The first image is a simple vector rectangle. I sized it at 16x16, but anything over that size will be scaled down to 16x16 assuming you have Windows 7 the default-sized icons and not the small ones. Overlays do not appear when using small icons.
<Window.Resources>
<DrawingImage x:Key="OverlayImage">
<DrawingImage.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="Red">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0 0 16 16"
RadiusX="3"
RadiusY="3" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup.Children>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Window.Resources>
When you run the application, and click the “Add Overlay” button, you’ll see a red rounded rectangle fade in over the icon.
Note that the shape retains its proper transparency
Overlaying PNGs
Overlaying PNGs is just as easy.
The first thing I did was locate some free 16x16 PNG icons, and plop one of them into the project, with its build action set to “Resource”
Next, I added it to the resources section of the window, keeping the same key as the previous drawing image
<Window.Resources>
<DrawingImage x:Key="OverlayImage">
<DrawingImage.Drawing>
<ImageDrawing ImageSource="10.png"
Rect="0,0,16,16" />
</DrawingImage.Drawing>
</DrawingImage>
</Window.Resources>
That’s all you need to do. Since we used the base ImageSource class when casting in our code-behind, we don’t have to touch the code at all. When run, here’s what it looked like on my system:
Note that the “Rect” property of the ImageDrawing is required. If you leave it out, you won’t see any overlay icon on the taskbar.
I’ll have a video and source code for this example on windowsclient.net soon. Check back for the link when posted.
Update: The source and video may be found here.