0

I have WPF application implemented with classic MVVM pattern, however View, Model and ViewModel are three different projects in my solution.

I have well-known implementation of AsyncObservebleCollection in my ViewModel

public class MyVM : ViewModelBase
{
    private RelayCommand _runCommand;
    private AsyncObservebleCollection _messages;

    public AsyncObservebleCollection<Message> Messages 
    { 
       get 
       { 
          return _messages;
       } 
       set
       {
         _messages = value; NotifyPropertyChanged();
       }
    }

    public ICommand RunCommand
    {
        get
        {
            if (_runCommand == null)
            {
                _runCommand = new RelayCommand(executeParam =>
                    bq.QueueTask(this.ExecuteCommand),
                canExecuteParam => true);
            }
            return _runCommand;
        }
    }
}

bq.QueueTask(this.ExecuteCommand) -> backgroundWorker is executing command on the background thread and it updates Messages property which is bidden to my view.

Now, I am getting the thread violation exception because AsyncObservebleCollection doesn't have UI's SynchronizationContext, and since I do know that ViewModel should not know about the View, how do I solve my problem? How do I use my UI's SynchronizationContext to run my RelayCommand asynchronously and update the UI?

Thank you

inside
  • 3,047
  • 10
  • 49
  • 75

1 Answers1

0

If you don't have access to the Dispatcher, you can just pass a delegate of the BeginInvoke method to your class:

public class YourViewModel {
public YourViewModel(Action<Action> beginInvoke)
{
    this.BeginInvoke = beginInvoke;
}

protected Action<Action> BeginInvoke { get; private set; }

private void SomeMethod()
{
    this.BeginInvoke(() => DoSomething());
} }

Then to instantiate it (from a class that has access to the dispatcher):

var dispatcherDelegate = action => Dispatcher.BeginInvoke(action); 
var viewModel = new YourViewModel(dispatcherDelegate);
Amr Reda
  • 632
  • 7
  • 18
  • You may not actually need the dispatcher. If you bind properties on your viewmodel to GUI elements in your view, the WPF binding mechanism automatically marshals the GUI updates to the GUI thread using the dispatcher. but there are plenty of situations, you might need to do this, Imagine an ObservableCollection bound to the UI and you trying to call _collection.Add() from a worker thread – Amr Reda Feb 06 '15 at 16:30