views:

46

answers:

2

Here's my situation:

I've got a User interface ItemsControl "ResultsPresenter" (WPF) pulling from a ListCollectionView that uses a BindingList "Results" from a non-UserInterface class as the ListCollectionView.Source property.

Whenever I make a change to "Results" such as an add operation, I get a NotSupportedException, insisting that {"This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread."}

It looks as if this error is coming from the "Results" collection, but the error information seems distinctly WPF generated. I'd like to know why I am throwing this error, and how to resolve it WITHOUT exposing the class that contains "Results" to WPF related code.

NOTE:

This solution came about after it was causing this error while looking directly at the "Results" property for binding, the ListCollectionView was only introduced to try and remedy this situation and is more than likely not part of the problem.

+1  A: 

The event raised by your Results collection is handled by the ListCollectionView to notify the UI. If this happens on a non-UI thread, you get this exception.

So you should never modify a UI-bound collection from a non-UI thread, unless it explicitly supports it. I wrote such a class that supports it some time ago, you can find it here.

Thomas Levesque
however, this problem existed before the ListCollectionView was introduced, so either it's the same issue manifesting differently or it's a different issue.I'm not 100% familiar with this error or how to resolve it.
Firoso
What do you mean by "before the ListCollectionView was introduced" ? Were you binding directly to the collection ? In that case a CollectionView is implicitly created by WPF, so it's eventually the same as your current situation
Thomas Levesque
OKay then that would be what was happening. With that being said, what can I do to resolve this? Should I be using an event and wrapping the target collection in a proxy collection that does all of it's updates on the UI thread?
Firoso
Try using the DispatcherHelper class that's in the MVVM Light Toolkit to make the calls that modify your collection.
Matt Casto
@firoso, did you check out the link I posted ? If you use that collection instead of a normal ObservableCollection, is will raise the CollectionChanged event on the dispatcher thread
Thomas Levesque
+1  A: 

This has been a known issue with collection changed notifications since WPF was called Avalon. See Bea Stollnitz's blog post on the subject.

You can work around it pretty easily by doing the collection changes on the dispatcher thread. Since I'm guessing you have a long running operation returning items or changes I'd recommend looking into Rx and using the ObserveOnDispatcher setting of IObservable. Rx in general makes this sort of thing much easier than it was in the past.

Bryan Anderson
Rx doesn't seem to be an applicable solution in this case, either way, I don't see what the point of having bindings to collections are if you can't update them through something other than the user interface. Is there a known best practice for getting around this without relying on 3rd party libraries or breaking encapsulation?
Firoso
Rx is a first party library (made by Microsoft). You can update collections in whatever assembly you want as long as you are running on the UI thread. In practice this rarely causes problems which is why they still haven't gotten around to fixing the issue.
Bryan Anderson