Remember, this is from an unrelated project, but I shoehorned this in. It won't compile as is, because some code I can't distribute is needed. I also replaced some functional code with placeholder code. But it should get the general idea across.
View Class
public partial class WorkerClassView : Window
{
private WorkerClassViewModel ViewModel { get; set; }
public WorkerClassView()
{
InitializeComponent();
this.ProgressEvent = this.OnProgress;
pbrStatus.Maximum = 100;
pbrStatus.Minimum = 0;
this.ViewModel = new WorkerClassViewModel(this.ProgressEvent);
this.DataContext = this.ViewModel;
this.Loaded += new RoutedEventHandler(WorkerClassView_Loaded);
}
private void WorkerClassView_Loaded(object sender, RoutedEventArgs e)
{
var inputBindings = new InputBindingCollection();
inputBindings.Add(new InputBinding(this.ViewModel.StartCommand, new KeyGesture(Key.S, ModifierKeys.Control | ModifierKeys.Alt)));
}
private ProgressChangedEventHandler ProgressEvent;
private void OnProgress(object sender, ProgressChangedEventArgs e)
{
pbrStatus.Value = e.ProgressPercentage >= pbrStatus.Minimum && e.ProgressPercentage <= pbrStatus.Maximum ? e.ProgressPercentage : 0;
pbrStatus.Refresh();
txtStatus.Text = e.UserState.ToString();
txtStatus.Refresh();
}
}
Worker Class
public abstract class WorkerBase: IWorker
{
protected string WorkerName
{
get;
private set;
}
public WorkerBase(string workerName)
{
this.WorkerName = workerName;
}
public void Execute(ProgressChangedEventHandler callback)
{
this.Initialize(callback);
this.DoWork(callback);
this.Finalize(callback);
}
private void Finalize(ProgressChangedEventHandler callback)
{
if (callback != null)
{
callback(this, new ProgressChangedEventArgs(100, string.Format("Worker {0} Complete!", this.WorkerName)));
}
}
protected abstract void DoWork(ProgressChangedEventHandler callback);
private void Initialize(ProgressChangedEventHandler callback)
{
if (callback != null)
{
callback(this, new ProgressChangedEventArgs(0, string.Format("Worker {0} Reporting!", this.WorkerName)));
}
}
}
ViewModel Class
public class WorkerClassViewModel
{
private ProgressChangedEventHandler CallBack = null;
private bool Executing { get; set; }
public WorkerClassViewModel(ProgressChangedEventHandler callback)
{
this.CallBack = callback;
this.Executing = false;
this.StartCommand = new RelayCommand(param => this.StartCommandExecute(), param => this.StartCommandCanExecute);
this.CloseCommand = new RelayCommand(param => this.CloseCommandExecute(), param => this.CloseCommandCanExecute);
}
private void StartWorkers()
{
this.Executing = true;
try
{
SimpleWorker workerOne = new SimpleWorker("Discipline");
SimpleWorker workerTwo = new SimpleWorker("Conviction");
workerOne.Execute(this.CallBack);
workerTwo.Execute(this.CallBack);
}
finally
{
this.Executing = false;
}
}
public ICommand StartCommand
{
get;
private set;
}
protected bool StartCommandCanExecute
{
get
{
return !this.Executing;
}
}
protected void StartCommandExecute()
{
this.StartWorkers();
}
public ICommand CloseCommand
{
get;
private set;
}
protected bool CloseCommandCanExecute
{
get
{
return !this.Executing;
}
}
protected void CloseCommandExecute()
{
}
}
The View Class (the form) instantiates the ViewModel, and passes it a reference to the callback. Then when the ViewModel is told to execute, it passes this callback to the workers. At any of these states, the callback can be done, and the form updated. Note that as is, the code is NOT threadsafe. So if you're going to be using it threaded, you'd need to check to see if the UI is getting updated on the UI thread or on a background thread. If you are using threading, I can point you to a tutorial. But if you just want to update one form from a process, the callback should be all you need.