How to merge several observables using WhenAny (...) in ReactiveUI?

I have a question, which is a continuation of the next question raised on this site.

Is there a more elegant way to merge observables when the return type is unimportant?

I have IObservable<Unit>(say X) a reactive collection ( Y) and a property ( Z). The return type is not important. I just want to subscribe when any of these changes change.

I know how to observe all 3 and Subscribeusing Observable.Merge, as shown below.

Observable.Merge(X, Y.Changed, ObservableForProperty(Z).Select(_ => Unit.Default)).Subscribe(..)

And it works.

However, when I try to use WhenAny(...,....,....).Subscribe(), the subscription does not start when it changes X. What is the syntax for doing the above using WhenAny(...)and not Observable.Merge(..)?

I prefer to use WhenAny(....)because I use ReactiveUIin other places.

Example: Say I have a class derived from ReactiveObjectwith the following properties.

public class AnotherVM : ReactiveObject
{
    public bool IsTrue
    {
        get { return this.isTrue; }
        set { this.RaiseAndSetIfChanged(x => x.isTrue, ref this.isTrue, value); }
    }

    public IObservable<Unit> Data
    {
        get { return this.data; }
    }

    public ReactiveCollection MyCol
    {
       get { return Mycol; }
    }    
}

public class MyVM : ReactiveObject
{
    MyVM
    {
       // do WhenAny or Observable.Merge here....
    }
}

I want to observe the above properties in a class AnotherVMusing Observable.Merge(..)or WhenAny(...)in a class MyVM. I found that I do not always receive a notification when I subscribe to the above at MyVM, using WhenAny(...)or Merge(...)when one of the three properties changes.

+3
source share
2 answers

WhenAny It is not intended for monitoring sets of arbitrary observables; it is intended for controlling the properties of an object supported by ReactiveUI (for example, ReactiveObject or reactive collection).

Observable.Merge - .

, Data MyCol . Merge :

Observerable.Merge(this.WhenAnyValue(o=>o.IsTrue, v=>Unit.Default),
                   this.Data,
                   this.MyCol.CollectionChanged.Select(v=>Unit.Default))

... , . , - , , ?

RaiseAndSetIfChanged Switch - . this.data , ( ReactiveUI 5 +.NET 4.5 , RaiseAndSetIfChanged ):

public IObservable<Unit> Data
{
    get { return this.data; }
    private set { this.RaiseAndSetIfChanged(ref data, value); }
}

:

Observerable.Merge(this.WhenAnyValue(o=>o.IsTrue, v=>Unit.Default),
                   this.WhenAnyObservable(x => x.Data),
                   this.MyCol.CollectionChanged.Select(v=>Unit.Default))

AnyObservable :

WhenAny(x => x.Data, vm => vm.Value).Switch()

, Data . !

+5

.

IObservable<Unit> merged =
    Observerable.Merge
    ( this.WhenAnyValue(o=>o.IsTrue, v=>Unit.Default)
    , this.Data
    , this.MyCol.CollectionChanged.Select(v=>Unit.Default)
    )

, IObservable<Unit>.

IObservable<Unit> merged =
    Observerable.MergeToUnit
    ( this.WhenAnyValue(o=>o.IsTrue)
    , this.Data
    , this.MyCol.CollectionChanged
    )

MergeToUnit , .

WhenAny -

Observable.CombineLatest
  ( source0.WhenAnyValue(s=>s.FieldA)
  , source1.WhenAnyValue(s=>s.FieldB)
  , source2.WhenAnyValue(s=>s.FieldC)
  , source3.WhenAnyValue(s=>s.FieldD)
  , (a,b,c,d) => Process(a,b,c,d)
  )

.

+2

All Articles