Suppose I have a WPF two-way data binding between a source (CLR property) and a destination (UI control property). Now anytime the destination property is updated, I want to update the source property on a non-UI thread (not on Dispatcher thread). In my application, I am using Rx (Reactive Extension) Scheduler, thus, I plan to provide one Rx scheduler for the execution.
As an example, if I bind the property Value of the following object and the UI updates the property using the binding, I want the setter of Value property to be executed on an Rx scheduler I provided.
public class A : VMBase { // VMBase provides the plumbing of INotifyPropertyChanged
private string _Value;
public string Value {
get { return _Value; }
set { SetField(ref _Value, value, () => Value); }
}
}
It is possible to modify the source property's setter to switch the update to another thread.
public class A : VMBase { // VMBase provides the plumbing of INotifyPropertyChanged
private string _Value;
public string Value {
get { return _Value; }
set { GetScheduler().Schedule(() => SetField(ref _Value, value, () => Value)); }
}
}
However, in my case this is not practical because I need to ask my users to modify their codes.
Googling the issue, I found that I can create a custom WPF binding as follows: http://www.hardcodet.net/2008/04/wpf-custom-binding-class. However, I couldn't find where I should hook the code to invoke the update on the Rx scheduler.
Any solutions or hint ? I am also opened to solutions based on Reactive Extensions or Reactive UI.
Thanks.
It can introduce quite a bit more work, but you can use interactions to link Commands in your ViewModel to Events on your controls. This should allow you to intercept the event causing the value update on your ViewModel and set your Value property using whatever method you like. Here I've also used the MVVM Light framework's 'EventToCommand', but you can swap in
<i:InvokeCommandAction...
if you're using something else.Reconfigure this to suit whatever control/event you're using, then your codebehind/viewmodel class needs a RelayCommand called SomethingWentClickCommand to retrieve the new value and update your binding property accordingly.