Question

I'm trying to ObservableForProperty for multiple Reactive Observable Sequences. Here's the code.

using ReactiveUI;

public ReactiveUIDerivedClass<T> FName {get; private set;}
public ReactiveUIDerivedClass<T> MName {get; private set;}
public ReactiveUIDerivedClass<T> LName {get; private set;}

FName = new ReactiveUIDerivedClass<T>();
MName = new ReactiveUIDerivedClass<T>();
LName = new ReactiveUIDerivedClass<T>();

Here T is System.String. So, the below method works.

private void ObserveForPropertyInThreeFields()
{
  Observable.CombineLatest(FName.ObservableForProperty(p => p.Value),
                           MName.ObservableForProperty(p => p.Value),
                           LName.ObservableForProperty(p => p.Value))
            .Where(p => p.All(v => !string.IsNullOrWhiteSpace(v.Value)))
            .Subscribe(p => { /* do some stuff */ } );
}

Now, I want to achieve similar result where T for the properties are of three different types. When I used Observable.CombineLatest, I get the following error message.

The type arguments for method 'System.Reactive.Linq.Observable.CombineLatest (System.IObservable, System.IObservable, System.Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

Any ideas on how do I ObserveForProperty Change for three properties of different types?

Was it helpful?

Solution 2

I'm leaving out the specific detail of using ObservableForProperty here - it's only the fact that the types of the streams differ that is important, so we can look at this as a vanilla Rx problem.

If you have streams with differing types then obviously the compiler cannot merge them into a single type itself. You need to specify a result selector function as the final argument to CombineLatest to tell it how you want to do this: e.g. given the following source streams:

IObservable<T1> xs;
IObservable<T2> ys;
IObservable<T3> zs;

...then one easy option is to produce an anonymous type (as long as you aren't returning it outside of the function of course) e.g.:

Observable.CombineLatest(xs, ys, zs, (x,y,z) => new { x,y,z });

OTHER TIPS

This is actually built-in to ReactiveUI already, using a better method than ObservableForProperty, called WhenAnyValue:

this.WhenAnyValue(x => x.FName, x => x.MName, x => x.LName, 
    (first,middle,last) => new { first, middle, last });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top