/// <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);
        }
Esempio n. 2
0
        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);
        }