I have the following method in one of my services:
public async Task SelectTransmission(Transmission transmission) { await Task.Run(() => webService.UseTransmission(transmission)) .ContinueWith(task => transmissionRepository.CreateIfNotExists(transmission)) .ContinueWith(task => { transmissionRepository.UpdateWithConfiguration(transmission); sessionManager.StoreTransmission(transmission); eventAggregator.GetEvent<TransmissionSelectedEvent>().Publish(transmission); }, TaskScheduler.FromCurrentSynchronizationContext()); }
The last line of the ContinueWith:
eventAggregator.GetEvent<TransmissionSelectedEvent>().Publish(transmission);
publishes an event. So, in the ViewModel I'm listenning to that event with the following code:
public AsyncObservableCollection<PreviewInputViewModel> PreviewInputs { get; private set; } private void TransmissionSelected(Transmission transmission) { PreviewVM.OutputDefinition = transmission.OutputDefinition; orchestrator.Reset(); mixer.ConfigureOutput(transmission.OutputDefinition); PreviewInputs.Update(CreatePreviewInputsFromTransmissionInputs(transmission)); }
public class AsyncObservableCollection<T> : ObservableCollection<T> { private SynchronizationContext context = SynchronizationContext.Current; public AsyncObservableCollection() : base() { } public AsyncObservableCollection(IEnumerable<T> list) : base(list) { } public void Update(IEnumerable<T> list) { if (list == null) return; Clear(); foreach (T item in list) Add(item); } protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { if (SynchronizationContext.Current == context) RaiseCollectionChanged(e); //Execute the CollectionChanged event on the current thread else context.Post(RaiseCollectionChanged, e); //Post the CollectionChanged event on the creator thread } private void RaiseCollectionChanged(object param) { // We are in the creator thread, call the base implementation directly base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param); } protected override void OnPropertyChanged(PropertyChangedEventArgs e) { if (SynchronizationContext.Current == context) RaisePropertyChanged(e); //Execute the PropertyChanged event on the current thread else context.Post(RaisePropertyChanged, e); //Post the PropertyChanged event on the creator thread } private void RaisePropertyChanged(object param) { // We are in the creator thread, call the base implementation directly base.OnPropertyChanged((PropertyChangedEventArgs)param); } }
The above class I found here: http://www.thomaslevesque.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/
I only introduced another method Update(), so I don't have to always use Clear() then a foreach to Add items.
With all of that in place, I don't get NotSupportedException, however, it seems that Clear() method is not working, because the old items (before the PreviewInputs.Update(...)) are still in the UI.
Take a look at WPF FlashMessage
About.me