Пример #1
0
        /// <summary>
        /// Observe collection element's IObservable sequence.
        /// </summary>
        /// <typeparam name="TCollection">Type of collection</typeparam>
        /// <typeparam name="TElement">Type of collection element</typeparam>
        /// <typeparam name="TProperty">Type of observable property element</typeparam>
        /// <param name="source">Source collection</param>
        /// <param name="propertySelector">IObservable selection expression</param>
        /// <returns>IObservable sequence</returns>
        internal static IObservable <PropertyPack <TElement, TProperty> > ObserveElementObservableProperty <TCollection, TElement, TProperty>(this TCollection source, Expression <Func <TElement, IObservable <TProperty> > > propertySelector)
            where TCollection : INotifyCollectionChanged, IEnumerable <TElement>
            where TElement : class
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (propertySelector == null)
            {
                throw new ArgumentNullException(nameof(propertySelector));
            }

            var memberExpression = (MemberExpression)propertySelector.Body;
            var propertyInfo     = memberExpression.Member as PropertyInfo;

            if (propertyInfo == null)
            {
                throw new ArgumentException($"{nameof(propertySelector)} is not property expression");
            }

            var propertyName = default(string); // no use
            var getter       = AccessorCache <TElement> .LookupGet(propertySelector, out propertyName);

            return(This.ObserveElementCore <TCollection, TElement, PropertyPack <TElement, TProperty> >
                   (
                       source,
                       (x, observer) => getter(x).Subscribe(y =>
            {
                var pair = PropertyPack.Create(x, propertyInfo, y);
                observer.OnNext(pair);
            })
                   ));
        }
Пример #2
0
        /// <summary>
        /// Converts target property's ErrorsChanged to an observable sequence.
        /// </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>
        /// <returns></returns>
        public static IObservable <TProperty> ObserveErrorInfo <TSubject, TProperty>(
            this TSubject subject, Expression <Func <TSubject, TProperty> > propertySelector)
            where TSubject : INotifyDataErrorInfo
        {
            var accessor = AccessorCache <TSubject> .LookupGet(propertySelector, out var propertyName);

            var result = subject.ErrorsChangedAsObservable()
                         .Where(e => e.PropertyName == propertyName)
                         .Select(_ => accessor.Invoke(subject));

            return(result);
        }
Пример #3
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);
        }