Private void AddToCurrentOffers(IEnumerable offers) Just a helper method that can also be inlined as lambda Dispatcher.InvokeAsync(() => AddToCurrentOffers(filteredOffers)) Use this to alternatively invoke the add method asynchronously on the UI thread Dispatcher.Invoke(() => AddToCurrentOffers(filteredOffers)) Use this to invoke the add method synchronously on the UI thread Var filteredOffers = newOffers.Where(no => !_currentOffers.Any(co => co.Id = no.Id)).Select(MapOffer) ![]() The same as you do, but simplified with Linq to return a filtered enumerable public void HandleNewOffers(object sender, ICollection newOffers) Dispatcher solutionĪ more general way to resolve this issue is to delegate adding items to the UI thread. I recommend you to check the out reference for details on that. NET Framework 4.5 and perfectly valid, but you must ensure that there are no deadlocks with the synchronization mechanism of your choice, which can be tricky. Your approach using BindingOperations.EnableCollectionSynchronization is available since. In your example this is not the UI thread, but your worker thread. This control will then update its items on the same thread. When your collection changes, it will raise a CollectionChanged event, which will be handled by the control that binds the ObservableCollection. The exception occurs because of thread affinity in WPF, which is by design.īoth the ItemsControl and the CollectionView have affinity to the thread on which the ItemsControl was created, meaning that using them on a different thread is forbidden and throws an exception. ![]() If (!_currentOffers.Any(co => co.Id = no.Id)) Implement code to add newOffers to ObservableCollection Public void HandleNewOffers(object sender, ICollection newOffers) ReceivedNewOffers?.Invoke(this, newOffers) īindingOperations.EnableCollectionSynchronization(_currentOffers, _itemsLock) Protected virtual void OnReceivingNewOffers(ICollection newOffers) Public event EventHandler> ReceivedNewOffers Any new offers - save them in DB and signal event If(!_currentOffers.Any(co=>co.Id = o.Id)) Var webOffers = await _webAccess.GetLatestOffers() In my ServiceLayer public async void CheckForNewOffers_Tick(object sender, ElapsedEventArgs e) are there any obvious issues that it will cause? This works - but is it a good approach i.e. I did some reading and managed to fix this problem by adding a CollectionSynchronization lock The problem was as soon as new items arrived, the attempt to update the ObservableCollection triggered an error "This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread" My UI subscribes to this event and updates the ObservableCollection. The way I'm doing this is I have a ServiceLayer that checks for new items, saves them to the db, and triggers an event. ![]() My app needs to check a remote resource for new additions and when these arrive, update the GUI and store the items in a database. I have an ObservableCollection in my ViewModel which is being used by a Datagrid. I'm building a WPF application according to MVVM.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |