In my ViewModel
I'll often have code like the following:
public bool IsDownloading { get { return _isDownloading.Value; } }
private ObservableAsPropertyHelper<bool> _isDownloading;
...
FileDownloader.WhenAny(x => x.IsDownloading, x => x.Value)
.ToProperty(this, x => x.IsDownloading, out _isDownloading, false, RxApp.MainThreadScheduler);
Note the last RxApp.MainThreadScheduler
argument - that makes sure that all updates to the IsDownloading
property happen on the main UI thread.
The reason for that is because of what might subscribe to it. For example, in my view xaml I might have the following code:
this.OneWayBind(ViewModel, x => x.IsDownloading, y => y.DownloadProgress.IsActive);
Here you see that IsDownloading
is going to be routed to the IsActive
item on a control - so any updates must occur on the UI thread. So all of this works.
But I don't get why ReactiveUI
was designed this way. It seems like it is important to the View, not the VM, that the updates occur on the UI thread, so shouldn't Bind or OneWayBind
make sure it is on the right thread? In fact, if you look at the XML documentation for those routines, they talk about attaching things to View's, so the implication is that it should always be on the main thread.
So: Why doesn't OneWayBind
and Bind implicitly force the MainThread
? Have I missed something in how ReactiveUI
works (or can be made to work)?