In a WPF app that I'm writing using the MVVM pattern, I have a background process that doing it's thing, but need to get status updates from it out to the UI.
I'm using the MVVM pattern, so my ViewModel knows virtually nothing of the view (UI) that is presenting the model to the user.
Say I have the following method in my ViewModel:
public void backgroundWorker_ReportProgress(object sender, ReportProgressArgs e)
{
this.Messages.Add(e.Message);
OnPropertyChanged("Messages");
}
In my view, I have a ListBox bound to the Messages property (a List<string>
) of the ViewModel. OnPropertyChanged
fulfills the role of the INotifyPropertyChanged
interface by calling a PropertyChangedEventHandler
.
I need to ensure that OnPropertyChanged
is called on the UI thread - how do I do this? I've tried the following:
public Dispatcher Dispatcher { get; set; }
public MyViewModel()
{
this.Dispatcher = Dispatcher.CurrentDispatcher;
}
Then adding the following to the OnPropertyChanged
method:
if (this.Dispatcher != Dispatcher.CurrentDispatcher)
{
this.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadStart(delegate
{
OnPropertyChanged(propertyName);
}));
return;
}
but this did not work. Any ideas?
WPF automatically marshals property changes to the UI thread. However, it does not marshal collection changes, so I suspect your adding a message is causing the failure.
You can marshal the add manually yourself (see example below), or use something like this technique I blogged about a while back.
Manually marshalling:
public void backgroundWorker_ReportProgress(object sender, ReportProgressArgs e)
{
Dispatcher.Invoke(new Action<string>(AddMessage), e.Message);
OnPropertyChanged("Messages");
}
private void AddMessage(string message)
{
Dispatcher.VerifyAccess();
Messages.Add(message);
}
I REALLY like Jeremy's answer: Dispatching In Silverlight
Summary:
Placing Dispatcher in ViewModel seems inelegant
Creating an Action<Action> property, set it to just run the action in the VM constructor
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With