The ICommand
interface provides a nice way of binding WPF buttons to methods in a view model. If those methods use any amount of time, though, you'll want to run them in a background thread.
This implementation of ICommand
is an easily-extendable way to run methods in an async manner when a button is clicked. The base class creates a BackgroundWorker
that runs a proxy for the Execute
method. All you have to do is override OnExecute
.
The...
BeforeExecute
...method allows you to run operations on the UI thread immediately before the BackgroundWorker
does its async operation.
The...
AfterExecute
...method allows you to run operations after the BackgroundWorker
completes its work. It also provides the Exception
object (if one was thrown) that was thrown in the background thread.
public class AsyncCommandBase : ICommand
{
protected void RaiseCanExecuteChanged()
{
if (CanExecuteChanged != null) CanExecuteChanged(this, new EventArgs());
}
protected virtual void BeforeExecute(object parameter) { }
protected virtual void OnExecute(object parameter) { }
protected virtual void AfterExecute(object parameter, Exception error) { }
public event EventHandler CanExecuteChanged;
public virtual bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
BeforeExecute(parameter);
var bgw = new BackgroundWorker();
bgw.DoWork += (s, e) =>
{
OnExecute(parameter);
};
bgw.RunWorkerCompleted += (s, e) =>
{
AfterExecute(parameter, e.Error);
};
bgw.RunWorkerAsync();
}
}