/// <summary> /// <para>Converts NotificationObject's property to ReactiveProperty. Value is two-way synchronized.</para> /// <para>PropertyChanged raise on selected scheduler.</para> /// </summary> /// <param name="propertySelector">Argument is self, Return is target property.</param> /// <param name="convert">Convert selector to ReactiveProperty.</param> /// <param name="convertBack">Convert selector to source.</param> /// <param name="mode">ReactiveProperty mode.</param> public static ReactiveProperty <TResult> ToReactivePropertyAsSynchronized <TSubject, TProperty, TResult>( this TSubject subject, Expression <Func <TSubject, TProperty> > propertySelector, Func <TProperty, TResult> convert, Func <TResult, TProperty> convertBack, IScheduler raiseEventScheduler, ReactivePropertyMode mode = ReactivePropertyMode.DistinctUntilChanged | ReactivePropertyMode.RaiseLatestValueOnSubscribe) where TSubject : INotifyPropertyChanged { string propertyName; // no use var setter = AccessorCache <TSubject> .LookupSet(propertySelector, out propertyName); var result = subject.ObserveProperty(propertySelector, isPushCurrentValueAtFirst: true) .Select(convert) .ToReactiveProperty(raiseEventScheduler, mode: mode); result.Select(convertBack).Subscribe(x => setter(subject, x)); return(result); }
/// <summary> /// Converts NotificationObject's property changed to an observable sequence. /// </summary> /// <param name="propertySelector">Argument is self, Return is target property.</param> /// <param name="isPushCurrentValueOnSubscribe">Push current value on first subscribe.</param> public static IObservable <TProperty> ObserveProperty <TSubject, TProperty>( this TSubject subject, Expression <Func <TSubject, TProperty> > propertySelector, bool isPushCurrentValueAtFirst = true) where TSubject : INotifyPropertyChanged { string propertyName; var accessor = AccessorCache <TSubject> .LookupGet(propertySelector, out propertyName); var isFirst = true; var result = Observable.Defer(() => { var flag = isFirst; isFirst = false; var q = subject.PropertyChangedAsObservable() .Where(e => e.PropertyName == propertyName) .Select(_ => accessor.Invoke(subject)); return((isPushCurrentValueAtFirst && flag) ? q.StartWith(accessor.Invoke(subject)) : q); }); return(result); }