If you ever work with Windows 7, you already noticed that some Applications could show progress of a long process directly in their icon placed on Windows 7 Taskbar. Good example of this functionality is Internet Explorer when it download a file from Internet or Windows Explorer when you copy/move a file from one location to another. Before .NET Framework 4 era you have had to use external libraries to do this or implement PInvoke by yourself. Now, in your WPF 4 Applications you can use .NET 4 functionality. Here is step-by-step guideline how to do this.
1. Open your progress dialog XAML file. Create reference to Windows.TaskbarItemInfo as very top item of your dialog as shown below (lines 7-9):
1: <Window x:Class="IconProgressDemo.MainWindow"
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: Title="MainWindow" Height="130" Width="490">
5:
6: <!-- Reference to TaskbarItemInfo: -->
7: <Window.TaskbarItemInfo>
8: <TaskbarItemInfo />
9: </Window.TaskbarItemInfo>
10:
11: <Grid>
12: <StackPanel>
13: <!-- Regular WPF ScrollBar: -->
14: <ProgressBar Name="progressBar" HorizontalAlignment="Stretch" Height="25" />
15:
16: <!-- Start long process by pushing this button: -->
17: <Button HorizontalAlignment="Center" Margin="0,20" Width="65" Height="25" Click="Button_Click">Start!</Button>
18: </StackPanel>
19: </Grid>
20: </Window>
21:
22:
2. Switch to code behind of this dialog. Before process start, set a process state (line #52 below). I’ll explain possible states later. Let start with Normal.
3. Pass a process value to TaskbarItemInfo at the same time as to regular progress bar (lines 65-70).
4. When process finishes toy may want to reset both progress bar and TaskbarItemInfo (lines 58-63).
5. Run this example and press Start button. You will see that Task bar icon shows green progress over it self.

Now, as promised, let see what other ProgressState values for.
TaskbarItemInfo.ProgressState could be one of the following values:
Normal. As you saw above, this value shows regular green progress on App’s icon.
None. This is default value. This is why it’s important to change this value to any other before you start the process. Otherwise you won’t see any progress on your App icon.
Error. Show red progress bar and suitable for emerging cases when, for example, a non-critical error occurs and you don’t want to interrupt the process but let customer know about such case.
Indeterminate. Shows green ‘wave’ or ‘pulse’. Good for processes when you don’t know how long they will take and have to wait until they finish.
Paused. Shows yellow progress and good for interrupted processes. But note that switching to this value doesn’t interrupt the process it self, you still have to do this manually.
The pictures below illustrate Error, Indeterminate and Paused values of ProgressState property:
And here is full code behind of this example:
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5: using System.Windows;
6: using System.Windows.Controls;
7: using System.Windows.Data;
8: using System.Windows.Documents;
9: using System.Windows.Input;
10: using System.Windows.Media;
11: using System.Windows.Media.Imaging;
12: using System.Windows.Navigation;
13: using System.Windows.Shapes;
14: using System.Threading;
15: using System.ComponentModel;
16:
17: namespace IconProgressDemo
18: {
19: /// <summary>
20: /// Interaction logic for MainWindow.xaml
21: /// </summary>
22: public partial class MainWindow : Window
23: {
24: public MainWindow()
25: {
26: InitializeComponent();
27: }
28:
29: private void Button_Click(object sender, RoutedEventArgs e)
30: {
31: // Simulate long process by using BackgroundWorker:
32: using (BackgroundWorker bw = new BackgroundWorker ())
33: {
34: bw.WorkerReportsProgress = true ;
35:
36: // Pass process data:
37: bw.ProgressChanged += new ProgressChangedEventHandler (bw_ProgressChanged);
38:
39: // Reset the counter:
40: bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler (bw_RunWorkerCompleted);
41:
42: bw.DoWork += (p, ev) =>
43: {
44: for (int i = 0; i <= 100; i += 10)
45: {
46: Thread .Sleep(1000);
47: ((BackgroundWorker )p).ReportProgress(i);
48: }
49: };
50:
51: // Set the progress state:
52: TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState .Normal;
53:
54: bw.RunWorkerAsync();
55: }
56: }
57:
58: void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
59: {
60: // The process was finished, reset the counter:
61: progressBar.Value = 0;
62: TaskbarItemInfo.ProgressValue = 0;
63: }
64:
65: void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
66: {
67: // Pass process counter to both ProgressBar and TaskbarItemInfo:
68: progressBar.Value = e.ProgressPercentage;
69: TaskbarItemInfo.ProgressValue = (double )e.ProgressPercentage / 100;
70: }
71: }
72: }
73:
74:
Have fun!
Technorati Tags:
.NET4,
WPF4
1f3ca0df-4a66-40f6-a5c2-fb4cfd364d17|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04