Welcome to Pete Brown's 10rem.net

First time here? If you are a developer or are interested in Microsoft tools and technology, please consider subscribing to the latest posts.

You may also be interested in my blog archives, the articles section, or some of my lab projects such as the C64 emulator written in Silverlight.

(hide this)

Creating Dynamic Windows 7 Taskbar Overlay Icons

Pete Brown - 29 May 2010

This is adapted from my recent "Creating your First WPF Application" post. I felt the dynamic overlay was interesting enough to pull out into a separate post.

WPF has good integration with the Windows 7 taskbar. One of the more interesting ways to integrate with the taskbar is to show an overlay icon. Most examples of this show how to overlay a static image or some visuals. I wanted to go one step further and display something more dynamic, generated at runtime.

Creating the Project

Create a new WPF windows application Project. The name is not important.

On the MainWindow, drag a textblock, a textbox, and a button. Name the TextBox "EnteredCount" and set the text property of the TextBlock to "Count". Finally, name the button "UpdateCount" with content of "Update".

<Grid>
    <TextBlock Height="23"
                HorizontalAlignment="Left"
                Margin="22,71,0,0"
                x:Name="textBlock1"
                Text="Count"
                VerticalAlignment="Top" />
    <TextBox Height="23"
                HorizontalAlignment="Left"
                Margin="92,68,0,0"
                x:Name="EnteredCount"
                VerticalAlignment="Top"
                Width="120" />
    <Button Content="Update"
            Height="23"
            HorizontalAlignment="Left"
            Margin="92,105,0,0"
            x:Name="UpdateCount"
            VerticalAlignment="Top"
            Width="75" />
</Grid>

The resulting window (in the designer) will look something like this:

image

Assigning the Application Icon

Find or create an interesting icon for the application. I picked up a set of free icons some time ago.

Drag the icon into your project. Then, open up the properties for MainWindow and click the […] button to the right of the Icon property. Pick the icon you just added. Here's what it looks like on my application:

image

The XAML for the MainWindow will be modified to reflect the new icon property, as seen in the following section.

Supporting Taskbar Integration

Overlay icons can be static bitmaps or vectors set up as XAML resources, or they can be images you create on the fly in code. Last December, I wrote about how to use taskbar icons in your WPF 4 applications. I want to show an overlay icon that displays a value entered in the TextBox. Of course, in your own applications, this value would likely be a count of items in a collection or some other calculated value.

The first thing we need to do is create an instance of the TaskbarItemInfo class. You can do this from code, or as I prefer, directly in the XAML for the window.

<Window x:Class="WpfApplication32.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        Icon="/WpfApplication32;component/folder_web.ico">
    <Window.TaskbarItemInfo>
        <TaskbarItemInfo />
    </Window.TaskbarItemInfo>
...

TaskbarItemInfo provides access to any taskbar-related functionality you will use in your application. Its capabilities extend beyond the simple overlay seen here. For other ways to use it, be sure to visit the Windows 7 videos section on WindowsClient.net.

The next step is to create some code and XAML that will take the entered number, and create an image with that number. The image will be a red circle with a white border and white text.

Adding the Icon Template

For this, I used a data template, much like you would for a ListBox. However, I included the template as a resource for the Window rather than as a child assigned to a property of another control. As it is a resource, we can load it pretty much anywhere we need to. In this case, I load it via code.

Here's the template. Place it in the xaml between the ending TaskbarItemInfo tag and the opening grid tag

<Window.Resources>      
    <DataTemplate x:Key="OverlayIcon">
        <Grid Width="20" Height="20">
            <Ellipse Fill="Red"
                        Stroke="White"
                        StrokeThickness="2"/>

            <TextBlock Text="{Binding}"
                        TextAlignment="Center"
                        Foreground="White"
                        FontWeight="Bold"
                        Height="16"
                        VerticalAlignment="Center"
                        FontSize="12">
                <TextBlock.Effect>
                    <DropShadowEffect ShadowDepth="0" />
                </TextBlock.Effect>
            </TextBlock>
        </Grid>
    </DataTemplate>
</Window.Resources>

Rendering the Icon

Here's the code to load the template and render it to a bitmap. Double-click the button on the form and put this into the event handler.

private void UpdateCount_Click(object sender, RoutedEventArgs e)
{
    int iconWidth = 20;
    int iconHeight = 20;

    string countText = EnteredCount.Text.Trim();

    RenderTargetBitmap bmp =
        new RenderTargetBitmap(iconWidth, iconHeight, 96, 96, PixelFormats.Default);

    ContentControl root = new ContentControl();

    root.ContentTemplate = ((DataTemplate)Resources["OverlayIcon"]);
    root.Content = countText;

    root.Arrange(new Rect(0, 0, iconWidth, iconHeight));

    bmp.Render(root);

    TaskbarItemInfo.Overlay = (ImageSource)bmp;
}

In this listing, I first get the count value from the TextBox. I then create a RenderTargetBitmap. The RenderTargetBitmap allows you to take visuals (from code or xaml) and render them out to a bitmap. That bitmap is what I pass to the Overlay property of the TaskBarItemInfo as the last step.

Before that, however, I create a ContentControl and assign the OverlayIcon resource (from xaml) as its data template. There are other ways to accomplish this using LoadContent and setting the data context, but the ContentControl approach is both easy and efficient.

I then tell the content control to render the context class as its template. Doing this makes the binding statements in our template work correctly.

Finally, I render the content control to the bitmap, and assign the bitmap to the overlay icon.

When you run the application, enter a value and hit the button, you'll see the taskbar icon displays an overlay:

image

Looks pretty good. You can play around with the visuals, of course, to create any type of notification you may want. In most Windows installations, it will render at 16x16 resolution, but you'll need to support 20x20 for higher DPI displays.

Conclusion

That's all there is to creating your own dynamic icon overlays from XAML markup. I hope to see functionality like this in your own upcoming applications.

       

Source Code and Related Media

Download /media/56256/dynamicwindows7taskbaroverlayiconssource.zip
posted by Pete Brown on Saturday, May 29, 2010
filed under:        

6 comments for “Creating Dynamic Windows 7 Taskbar Overlay Icons”

  1. Tuckersays:
    Great post. Super helpful and very concise! I was wondering if there is a way to save the overlay so that when I open the executable it reminds me what I typed in previously.

Comment on this Post

Remember me