/// <summary> /// Observe collection element's property. /// </summary> /// <typeparam name="TCollection">Type of collection</typeparam> /// <typeparam name="TElement">Type of element</typeparam> /// <typeparam name="TProperty">Type of property</typeparam> /// <param name="source">Data source</param> /// <param name="propertySelector">Property selection expression</param> /// <param name="isPushCurrentValueAtFirst">Push current value on first subscribe</param> /// <returns>Property value sequence</returns> public static IObservable <PropertyPack <TElement, TProperty> > ObserveElementProperty <TCollection, TElement, TProperty>(TCollection source, Expression <Func <TElement, TProperty> > propertySelector, bool isPushCurrentValueAtFirst = true) where TCollection : INotifyCollectionChanged, IEnumerable <TElement> where TElement : class, INotifyPropertyChanged { 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"); } return(ObserveElementCore <TCollection, TElement, PropertyPack <TElement, TProperty> > ( source, (x, observer) => x.ObserveProperty(propertySelector, isPushCurrentValueAtFirst).Subscribe(y => { var pair = PropertyPack.Create(x, propertyInfo, y); observer.OnNext(pair); }) )); }
/// <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> public static IObservable <PropertyPack <TElement, TProperty> > ObserveElementObservableProperty <TCollection, TElement, TProperty>(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)); } if (!(propertySelector.Body is MemberExpression memberExpression)) { if (!(propertySelector.Body is UnaryExpression unaryExpression)) { throw new ArgumentException(nameof(propertySelector)); } var operand = unaryExpression.Operand as MemberExpression; if (operand == null) { throw new ArgumentException(nameof(propertySelector)); } memberExpression = operand; } var propertyInfo = memberExpression.Member as PropertyInfo; if (propertyInfo == null) { throw new ArgumentException($"{nameof(propertySelector)} is not property expression"); } // no use var getter = AccessorCache <TElement> .LookupGet(propertySelector, out var propertyName); return(ObserveElementCore <TCollection, TElement, PropertyPack <TElement, TProperty> > ( source, (x, observer) => getter(x).Subscribe(y => { var pair = PropertyPack.Create(x, propertyInfo, y); observer.OnNext(pair); }) )); }