/// <summary> /// <para>Converts NotificationObject's property to ReactiveProperty. Value is two-way synchronized.</para> /// <para>PropertyChanged raise on selected scheduler.</para> /// </summary> /// <typeparam name="TSubject">The type of the subject.</typeparam> /// <typeparam name="TProperty">The type of the property.</typeparam> /// <param name="subject">The subject.</param> /// <param name="propertySelector">Argument is self, Return is target property.</param> /// <param name="raiseEventScheduler">The raise event scheduler.</param> /// <param name="mode">ReactiveProperty mode.</param> /// <param name="ignoreValidationErrorValue">Ignore validation error value.</param> /// <returns></returns> public static ReactiveProperty <TProperty> ToReactivePropertyAsSynchronized <TSubject, TProperty>( this TSubject subject, Expression <Func <TSubject, TProperty> > propertySelector, IScheduler raiseEventScheduler, ReactivePropertyMode mode = ReactivePropertyMode.DistinctUntilChanged | ReactivePropertyMode.RaiseLatestValueOnSubscribe, bool ignoreValidationErrorValue = false) where TSubject : INotifyPropertyChanged { var setter = AccessorCache <TSubject> .LookupSet(propertySelector, out _); var result = subject.ObserveProperty(propertySelector, isPushCurrentValueAtFirst: true) .ToReactiveProperty(raiseEventScheduler, mode: mode); result .Where(_ => !ignoreValidationErrorValue || !result.HasErrors) .Subscribe(x => setter(subject, x)); return(result); }
private static IObservable <TProperty> ObserveSimpleProperty <TSubject, TProperty>( this TSubject subject, Expression <Func <TSubject, TProperty> > propertySelector, bool isPushCurrentValueAtFirst = true) where TSubject : INotifyPropertyChanged { var isFirst = true; var accessor = AccessorCache <TSubject> .LookupGet(propertySelector, out var propertyName); return(Observable.Defer(() => { var flag = isFirst; isFirst = false; var q = subject.PropertyChangedAsObservable() .Where(e => e.PropertyName == propertyName || string.IsNullOrEmpty(e.PropertyName)) .Select(_ => accessor.Invoke(subject)); return (isPushCurrentValueAtFirst && flag) ? q.StartWith(accessor.Invoke(subject)) : q; })); }
/// <summary> /// Converts NotificationObject's property changed to an observable sequence. /// </summary> /// <param name="propertySelector">Argument is self, Return is target property.</param> /// <param name="isPushCurrentValueAtFirst">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); }