Skip to content

Commit 081dae9

Browse files
committed
Update README.md
1 parent 274242f commit 081dae9

File tree

1 file changed

+120
-2
lines changed

1 file changed

+120
-2
lines changed

README.md

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,122 @@
1-
wpf-mvvm-task-progress-dialog
1+
WPF MVVM Progress Dialog Example
22
=============================
33

4-
An MVVM-style progress meter dialog using the .NET 4.5 Task Parallel Library (TPL).
4+
This is a quick example WPF application that shows an MVVM-style progress meter dialog, using the .NET 4.5 Task Parallel Library (TPL):
5+
6+
* An injectable, stateless IProgressDialogService, that can be injected for unit testing purposes.
7+
* A progress meter using .NET 4 Tasks (not BackgroundWorkers).
8+
* Cancelling of Tasks via CancellationTokens.
9+
* Exception handling back to the original thread.
10+
* Reporting background progress updates via IProgress<T>.
11+
* Tasks can either be declared as void, or have a return value.
12+
* Using an attached property to hide [the close button in the progress dialog's title bar](http://stackoverflow.com/questions/743906/how-to-hide-close-button-in-wpf-window) using Win32 interop.
13+
* Using an attached property to implement a [close window command using MVVM](http://stackoverflow.com/questions/11945821/implementing-close-window-command-with-mvvm/).
14+
15+
Note it uses [MVVM light](http://mvvmlight.codeplex.com) for some INotifyPropertyChanged and DispatcherHelper stuff.
16+
17+
### Example Usage
18+
The following example shows how you might set up a simple progress dialog, that can be cancelled and reports progress.
19+
20+
```csharp
21+
public class MyLongRunningCommand : ICommand
22+
{
23+
IProgressDialogService dialogService;
24+
25+
public void Execute(object parameter)
26+
{
27+
dialogService.Execute(DoWork, new ProgressDialogOptions { WindowTitle = "Loading files" });
28+
}
29+
30+
void DoWork(CancellationToken cancellationToken, IProgress<string> progress)
31+
{
32+
for (int i = 0; i < 100; i++)
33+
{
34+
cancellationToken.ThrowIfCancellationRequested();
35+
36+
progress.Report(String.Format("Processing task {0}", i));
37+
38+
// Do some work
39+
Thread.Sleep(TimeSpan.FromMilliseconds(100));
40+
}
41+
}
42+
43+
...
44+
}
45+
```
46+
47+
### Example Usage - Composing Multiple Tasks
48+
The following example shows how you might set up a progress dialog that is composed of multiple tasks chained together (that are cancellable and each report progress).
49+
50+
```csharp
51+
public class MyLongRunningCommand : ICommand
52+
{
53+
readonly IProgressDialogService dialogService;
54+
55+
public void Execute(object parameter)
56+
{
57+
dialogService.Execute(DoWork, new ProgressDialogOptions { WindowTitle = "Loading files" });
58+
}
59+
60+
void DoWork(CancellationToken cancellationToken, IProgress<string> progress)
61+
{
62+
Task.Factory.StartNew(() => progress.Report("First"), cancellationToken)
63+
.ContinueWith(_ => Thread.Sleep(1000), cancellationToken)
64+
.ContinueWith(_ => progress.Report("Second"), cancellationToken)
65+
.ContinueWith(_ => Thread.Sleep(1000), cancellationToken)
66+
.Wait();
67+
}
68+
69+
...
70+
}
71+
```
72+
73+
### IProgressDialogService
74+
The following signatures are supported - Execute (no return value) and TryExecute (a return value is expected, but will return false if cancelled).
75+
```csharp
76+
public interface IProgressDialogService
77+
{
78+
/// <summary>
79+
/// Executes a non-cancellable task.
80+
/// </summary>
81+
void Execute(Action action, ProgressDialogOptions options);
82+
83+
/// <summary>
84+
/// Executes a cancellable task.
85+
/// </summary>
86+
void Execute(Action<CancellationToken> action, ProgressDialogOptions options);
87+
88+
/// <summary>
89+
/// Executes a non-cancellable task that reports progress.
90+
/// </summary>
91+
void Execute(Action<IProgress<string>> action, ProgressDialogOptions options);
92+
93+
/// <summary>
94+
/// Executes a cancellable task that reports progress.
95+
/// </summary>
96+
void Execute(Action<CancellationToken, IProgress<string>> action, ProgressDialogOptions options);
97+
98+
/// <summary>
99+
/// Executes a non-cancellable task, that returns a value.
100+
/// </summary>
101+
bool TryExecute<T>(Func<T> action, ProgressDialogOptions options, out T result);
102+
103+
/// <summary>
104+
/// Executes a cancellable task that returns a value.
105+
/// </summary>
106+
bool TryExecute<T>(Func<CancellationToken, T> action, ProgressDialogOptions options, out T result);
107+
108+
/// <summary>
109+
/// Executes a non-cancellable task that reports progress and returns a value.
110+
/// </summary>
111+
bool TryExecute<T>(Func<IProgress<string>, T> action, ProgressDialogOptions options, out T result);
112+
113+
/// <summary>
114+
/// Executes a cancellable task that reports progress and returns a value.
115+
/// </summary>
116+
bool TryExecute<T>(Func<CancellationToken, IProgress<string>, T> action, ProgressDialogOptions options, out T result);
117+
}
118+
```
119+
120+
### Credits
121+
122+
This is based upon Jürgen Bäurle's original blog post here: http://www.parago.de/2011/04/how-to-implement-a-modern-progress-dialog-for-wpf-applications/

0 commit comments

Comments
 (0)