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)

Showing Progress in the Windows 7 Taskbar with WPF 4 (and a short romp through Windows 7 cleartype settings)

Pete Brown - 29 October 2009

Have you ever copied a large number of files, or downloaded something big using IE? If so, you've probably seen the taskbar download progress indicator. This is a green progress bar that fills the area behind the application icon in the taskbar.

You can achieve the same effect in Windows 7 using .NET 4, with very little code. Let's run through how.

Project Setup

I created a simple WPF application in Visual Studio 2010. Nothing fancy, I kept the original MainWindow and simply worked with that. I named the project "Win7ProgressBar".

Next I added an icon to the project. I have a C64 logo icon I created for my Silverlight C64 emulator handy, so I used that.

MainWindow

I resized the main window to be a little smaller, gave it the title "Long Task" and assigned the icon to it. The resulting opening tag looks like this:

<Window x:Class="Win7ProgressBar.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Long Task" Height="241" Width="432"
        Icon="/Win7ProgressBar;component/AppIcon032.png">

Next, I added a progress bar and a textblock to the window:

<Grid>
    <ProgressBar Height="23"
                 HorizontalAlignment="Left"
                 Margin="36,88,0,0"
                 Name="progressBar1"
                 VerticalAlignment="Top"
                 Width="334" />
    <TextBlock Height="23"
               HorizontalAlignment="Left"
               Margin="36,24,0,0"
               Name="textBlock1"
               Text="This is a really long-running task"
               VerticalAlignment="Top"
               Width="201" />
</Grid>

Here's how the window looks in the VS2010 designer.

image

So far so good. I have a window and a progress bar, but no activity, and nothing that would as yet hook it up to the taskbar.

Taskbar wireup isn't automatic; it's something you need to opt into. You can do it in xaml, and you can do it in code. I used a mixture of both for this example. Since we still have the window xaml open, let's put that in there now.

Right after the opening tag for the window, and before the opening grid tag, add in this snip:

<Window.TaskbarItemInfo>
    <TaskbarItemInfo />
</Window.TaskbarItemInfo>

That simply news up a TasbarItemInfo class for us. If you look at the TasbarItemInfo tag, you'll see there's quite a bit more you can do right from within xaml. But I always do everything in xaml, so let's try some code instead :)

image

An aside on ClearType

The rather ugly font in the drop down is due to the settings on the monitor on which I took this shot (I have three displays). I need to readjust my cleartype settings for that display. If you have crappy-looking fonts in apps, you can simply go to Control Panel -> Fonts and then select the option to adjust the cleartype settings on your monitor.

image

Run through the wizard and answer the questions for which one looks best. You're better off not thinking and simply acting. The more you think about the answer, the less accurate you'll be. Go with your first impressions.

By way of comparison, here's the same thing, only snapped from my primary monitor, with good cleartype settings:

image

Notice the massive difference in the drop-down list? If not, scroll back up and look again.

Now, most people won't have to go through that wizard unless they get a drastically different display from what they started with. I needed to simply because I tested a special build of SL3 before it went live, and was specifically asked to look at the cleartype rendering. I played with the wizard and forgot to go back and fix it :)

Back to the TaskBar

Now that we have all the xaml in place, let's take a look at the code. I'm going to simulate a long-running activity simply by throwing in a background worker and having it run a tight loop with a bunch of thread sleeps in there.

Wire up the loaded event handler for the window, and let the IDE help you wire up the events for DoWork, ProgressChanged, RunWorkerCompleted.

Next, be sure to set the worker.WorkerReportsProgress to true, and then call the RunWorkerAsync() method to kick off the process. The resulting load event looks like this:

void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += new DoWorkEventHandler(worker_DoWork);
    worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
    worker.WorkerReportsProgress = true;
    worker.RunWorkerAsync();
}

Before we start reporting progress to the taskbar and the progress bar, let's set the starting ProgressState for the taskbar. You can set this multiple times throughout the life of the process to control various states. Here's what the states look like:

Normal (green progress bar)

image

Indeterminate (pulsing green wave)

image

Paused (yellow progress bar)

image

Error (red progress bar)

image

So, let's start it off at Normal. You could do this in the loaded event or in the constructor, or at any point during the process. I initialized it in the constructor.

public MainWindow()
{
    InitializeComponent();

    TaskbarItemInfo.ProgressState = TaskbarItemProgressState.Normal;

    Loaded += new RoutedEventHandler(MainWindow_Loaded);
}


Next, we need to handle reported background thread process status and use it to update both the progress bar in the window and the taskbar. That's really simple to do. Note, however, that the TaskbarItemInfo.ProgressValue is a double between 0 and 1 while the progressBar value is an integer between two numbers supplied by you (typically 0 and 100), so we'll need to adjust when we report progress.

void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
    TaskbarItemInfo.ProgressValue = (double)e.ProgressPercentage/100;
}

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    progressBar1.Value = 100;
    TaskbarItemInfo.ProgressValue = 1.0;
}

Finally, we need our worker itself. This is where you'd be doing something real, and time-consuming. Instead, I'll just do something really time-consuming :) It sleeps one second per iteration and then reports the current progress.

void worker_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i < 100; i += 10)
    {
        Thread.Sleep(1000);
        ((BackgroundWorker)sender).ReportProgress(i);
    }
}

Runtime

When you run the app, you'll see both the window and the taskbar update.

image

image

That was really easy. There are other things you can do with TaskbarItemInfo, such as changing your thumbnail and adding overlay icons. We'll look at those in an upcoming post.

A Word on Use

Be judicious with how you use progress reporting on Windows 7. You should only use it when the progress status will be meaningful to a user when running other applications. Consider the scenario of your app doing something that the user will typically alt-tab away from. If the app is doing something that the user will want to know when it has completed so they can take an action (like opening a downloaded zip) then the taskbar progress reporting will be good. If, however, you are doing something which will have other progress indicators (like playing a video, where it's obvious when the video ends because the user can see/hear it) or which won't have the user waiting with bated breath for it to finish, consider just using a regular old progress bar, preferably a non-modal one.

A video version of those, with source code, will be available on windowsclient.net I'll update this post with a link once that is up.

Update 12/16/2009: The video and source code are located here.

 

       
posted by Pete Brown on Thursday, October 29, 2009
filed under:        

9 comments for “Showing Progress in the Windows 7 Taskbar with WPF 4 (and a short romp through Windows 7 cleartype settings)”

  1. Tim Ellissays:
    "A video version of those, with source code, will be available on windowsclient.net I’ll update this post with a link once that is up."

    Any Idea when it will be ready?, or if it is already, can u provide a link?

    Thanks
  2. Petesays:
    @Abhijeet

    I noticed the same thing when I first used it :)

    None of my attempts to get animation/video in there worked. According to the Windows UI standards, you're not really *supposed* to animate that, but just thought it would be interesting if you could. You can probably switch overlays on a timer, but doubt it would happen fast enough (especially with the fade) to look like a real animation.

    Pete
  3. Petesays:
    @david

    done. I've taken down my old domain, but the mapping didn't quite work. If you run across this elsewhere, and don't want to wait for me, just change irritatedvowel.com to 10rem.net in the URLs

    Pete

Comment on this Post

Remember me

9 trackbacks for “Showing Progress in the Windows 7 Taskbar with WPF 4 (and a short romp through Windows 7 cleartype settings)”

  1. Scott Hanselman's Computer Zen - The Weekly Source Code 46 - Jeff Key rocks Taskbar Meters that Monitor your Windows 7 CPU and Memory and Disk in the Taskbarsays:
    PingBack from http://www.hanselman.com/blog/TheWeeklySourceCode46JeffKeyRocksTaskbarMetersThatMonitorYourWindows7CPUAndMemoryAndDiskInTheTaskbar.aspx
  2. Scott Hanselman's Computer Zen - The Weekly Source Code 46 - Jeff Key rocks Taskbar Meters that Monitor your Windows 7 CPU and Memory and Disk in the Taskbarsays:
    PingBack from http://www.hanselman.com/blog/TheWeeklySourceCode46JeffKeyRocksTaskbarMetersThatMonitorYourWindows7CPUAndMemoryAndDiskInTheTaskbar.aspx
  3. uberVU - social commentssays:
    This post was mentioned on Twitter by Pete_Brown: Blogged: Showing Progress in the Win7 Taskbar with WPF 4 (+ aside on Win7 cleartype settings) http://bit.ly/4mUmv1
  4. progg.rusays:
    Thank you for submitting this cool story - Trackback from progg.ru
  5. POKE 53280,0: Pete Brown's Blogsays:
    The Windows 7 taskbar is more than just a place to hold icons for running and pinned applications. Among
  6. Windows Client Newssays:
    The Windows 7 taskbar has a ton of interesting features you can use to provide information to your users