1

In my view I have a Grid that is bound to an ObservableCollection. My ViewModel contains the ObservableCollection

    public ObservableCollection<Session> Sessions
    {
        get
        {
            return _repository.GetSessions();
        }
        set
        {
            _sessions = value;
            NotifyPropertyChanged("Sessions");
        }
    }

When some action happens in another ViewModel, I publish an event to the event aggregator, I'm subscribing to that event in the ViewModel that contains the Sessions property and modifying an object in the Sessions ObjectCollection.

When I publish an event to the event aggregator from the UI thread, the subscriber's event handler does the work and the UI is updated as expected.

The problem is when I publish an event to the event aggregator from a background worker. The code in the subscriber is executed, but the UI is not updated.

Here's some code:

SecondaryViewModel.cs publishing events from the UI thread.

_eventAggregator.GetEvent<SomethingChangedEvent>().Publish("this changed");

In MainViewModel.cs I'm subscribing to the event and updating a property and the UI DOES update.

//The subscription
_eventAggregator.GetEvent<SomethingChangedEvent>().Subscribe(SomethingChangedEventHandler, ThreadOption.UIThread);

Background Worker

    //Check stuff in background
    private void CheckSessionsInBackground()
    {
        //Show your wait dialog
        var worker = new BackgroundWorker();
        worker.DoWork += DoWork;
        worker.RunWorkerCompleted += WorkerCompleted;
        worker.RunWorkerAsync();
    }

And in the DoWork Method I'm publishing an event

    private void DoWork(object sender, DoWorkEventArgs e)
    {
        //Some other work
        _eventAggregator.GetEvent<SomethingChangedEvent>().Publish("Changes from the background worker");

    }

If I stop execution in the handler I can confirm that the code is being executed, however the UI is not updated. My question is if it's possible to update a collection when a message is published to the eventaggregator in a background worker. I've looked at examples that use the Dispatcher, but none of them use the EventAggregator. Any help is welcome.

lopezbertoni
  • 3,551
  • 3
  • 37
  • 53
  • This might help .... https://msdn.microsoft.com/en-us/library/ms171728.aspx – Mick Jul 16 '15 at 02:16
  • Possibly a duplicate of ... http://stackoverflow.com/questions/2806814/backgroundworker-runworkercompleted-event Or http://stackoverflow.com/questions/5483565/how-to-use-wpf-background-worker?rq=1 – Mick Jul 16 '15 at 02:18
  • Thanks, I looked at those but they don't use the Event Aggregator. – lopezbertoni Jul 16 '15 at 02:20
  • 2
    Got some free critiques if you care. You're leaking resources. That background worker is just going to hang around, kept alive by the references hidden within the event, after it's completed. You should convert this over to using Tasks. It's trivial. Also, OC properties should be read only. Add/remove instances to/from the collection. Third, event aggregator isn't normally a pattern seen in MVVM. If it's harder to use than simply updating INPC properties on the VM, then why bother? –  Jul 16 '15 at 14:30
  • 1
    @Will Thanks, all critiques are always welcome and helpful. I ended up doing exactly as you say. To update the OC, I remove the object and re add the modified one and everything works as expected. – lopezbertoni Jul 16 '15 at 14:36

0 Answers0