/// <summary> /// Projects each element of a sequence to an <see cref="IBindableCollection{TElement}"/> and flattens the resulting sequences into one sequence. /// </summary> /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam> /// <typeparam name="TResult">The type of the elements of the sequence returned by <paramref name="selector"/>.</typeparam> /// <param name="source">A sequence of values to project.</param> /// <param name="selector">A transform function to apply to each element.</param> /// <param name="dependencyAnalysisMode">The dependency analysis mode.</param> /// <returns> /// An <see cref="IBindableCollection{TElement}"/> whose elements are the result of invoking the one-to-many transform function on each element of the input sequence. /// </returns> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="source"/> or <paramref name="selector"/> is null.</exception> public static IBindableCollection <TResult> SelectMany <TSource, TResult>(this IBindableCollection <TSource> source, Expression <Func <TSource, IBindableCollection <TResult> > > selector, DependencyDiscovery dependencyAnalysisMode) where TSource : class where TResult : class { source.ShouldNotBeNull("source"); return(source.Select(selector, dependencyAnalysisMode).UnionAll()); }
/// <summary> /// Applies an accumulator function over a sequence. The specified seed value is used as the /// initial accumulator value. /// </summary> /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam> /// <typeparam name="TAccumulate">The type of the accumulator value.</typeparam> /// <param name="source">An <see cref="IBindableCollection{TElement}"/> to aggregate over.</param> /// <param name="seed">The initial accumulator value.</param> /// <param name="func">An accumulator function to be invoked on each element.</param> /// <param name="dependencyAnalysisMode">The dependency analysis mode.</param> /// <returns>The final accumulator value.</returns> public static IBindable <TAccumulate> Aggregate <TSource, TAccumulate>(this IBindableCollection <TSource> source, TAccumulate seed, Expression <Func <TAccumulate, TSource, TAccumulate> > func, DependencyDiscovery dependencyAnalysisMode) { source.ShouldNotBeNull("source"); func.ShouldNotBeNull("func"); seed.ShouldNotBeNull("seed"); var compiledAccumulator = func.Compile(); var function = new Func <IBindableCollection <TSource>, TAccumulate>( sourceElements => { var current = seed; foreach (var sourceElement in sourceElements) { current = compiledAccumulator(current, sourceElement); } return(current); } ); var result = new CustomAggregator <TSource, TAccumulate>(source, function, source.Dispatcher); if (dependencyAnalysisMode == DependencyDiscovery.Enabled) { return(result.DependsOnExpression(func, func.Parameters[1])); } return(result); }
/// <summary> /// Determines whether a sequence contains any elements. /// </summary> /// <param name="source">The <see cref="IBindableCollection{TElement}" /> to check for emptiness.</param> /// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam> /// <returns>true if the source sequence contains any elements; otherwise, false.</returns> public static IBindable <bool> Any <TSource>(this IBindableCollection <TSource> source) { source.ShouldNotBeNull("source"); return(source.Count() .Switch() .Case(count => count >= 1, true) .Default(false) .EndSwitch()); }
/// <summary> /// Determines whether all elements of a sequence satisfy a condition. /// </summary> /// <param name="source">An <see cref="IBindableCollection{TElement}" /> that contains the elements to apply the predicate to.</param> /// <param name="predicate">A function to test each element for a condition.</param> /// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam> /// <returns> /// true if every element of the source sequence passes the test in the specified /// predicate, or if the sequence is empty; otherwise, false. /// </returns> public static IBindable <bool> All <TSource>(this IBindableCollection <TSource> source, Expression <Func <TSource, bool> > predicate) where TSource : class { source.ShouldNotBeNull("source"); predicate.ShouldNotBeNull("predicate"); return(source.Where(predicate).Count() .Switch() .Case(count => count >= 1, true) .Default(false) .EndSwitch()); }
/// <summary> /// Produces the set union of two sequences by using the default equality comparer. /// </summary> /// <typeparam name="TSource">The type of the elements of the input sequences.</typeparam> /// <param name="first">An <see cref="IBindableCollection{TElement}"/> whose distinct elements form the first set for the union.</param> /// <param name="second">An <see cref="IBindableCollection{TElement}"/> whose distinct elements form the second set for the union.</param> /// <returns> /// An <see cref="IBindableCollection{TElement}"/> that contains the elements from both input sequences, excluding duplicates. /// </returns> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="first"/> or <paramref name="second"/> is null.</exception> public static IBindableCollection <TSource> Union <TSource>(this IBindableCollection <TSource> first, IBindableCollection <TSource> second) where TSource : class { first.ShouldNotBeNull("first"); second.ShouldNotBeNull("second"); var sources = new BindableCollection <IBindableCollection <TSource> >(first.Dispatcher) { first, second }; return(new UnionIterator <TSource>(sources, first.Dispatcher)); }
/// <summary> /// Sorts the elements of a sequence in ascending order by using a specified comparer. /// </summary> /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam> /// <typeparam name="TKey">The type of the key returned by <paramref name="keySelector"/>.</typeparam> /// <param name="source">A sequence of values to order.</param> /// <param name="keySelector">A function to extract a key from an element.</param> /// <param name="comparer">An <see cref="T:System.Collections.Generic.IComparer`1"/> to compare keys.</param> /// <param name="dependencyAnalysisMode">The dependency analysis mode.</param> /// <returns> /// An <see cref="T:System.Linq.IOrderedEnumerable`1"/> whose elements are sorted according to a key. /// </returns> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="source"/> or <paramref name="keySelector"/> is null.</exception> public static IOrderedBindableCollection <TSource> OrderBy <TSource, TKey>(this IBindableCollection <TSource> source, Expression <Func <TSource, TKey> > keySelector, IComparer <TKey> comparer, DependencyDiscovery dependencyAnalysisMode) where TSource : class { source.ShouldNotBeNull("source"); keySelector.ShouldNotBeNull("keySelector"); var result = new OrderByIterator <TSource, TKey>(source, new ItemSorter <TSource, TKey>(null, keySelector.Compile(), comparer, true), source.Dispatcher); if (dependencyAnalysisMode == DependencyDiscovery.Enabled) { return(result.DependsOnExpression(keySelector.Body, keySelector.Parameters[0])); } return(result); }
/// <summary> /// Projects each element of a sequence into a new form. /// </summary> /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam> /// <typeparam name="TResult">The type of the value returned by <paramref name="selector"/>.</typeparam> /// <param name="source">A sequence of values to invoke a transform function on.</param> /// <param name="selector">A transform function to apply to each element.</param> /// <param name="dependencyAnalysisMode">The dependency analysis mode.</param> /// <returns> /// An <see cref="IBindableCollection{TElement}"/> whose elements are the result of invoking the transform function on each element of <paramref name="source"/>. /// </returns> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="source"/> or <paramref name="selector"/> is null.</exception> public static IBindableCollection <TResult> Select <TSource, TResult>(this IBindableCollection <TSource> source, Expression <Func <TSource, TResult> > selector, DependencyDiscovery dependencyAnalysisMode) where TSource : class { source.ShouldNotBeNull("source"); selector.ShouldNotBeNull("selector"); var result = new SelectIterator <TSource, TResult>(source, selector.Compile(), source.Dispatcher); if (dependencyAnalysisMode == DependencyDiscovery.Enabled) { result = result.DependsOnExpression(selector.Body, selector.Parameters[0]); } return(result); }
/// <summary> /// Applies an accumulator function over a sequence. /// </summary> /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam> /// <typeparam name="TResult">The type of the result.</typeparam> /// <param name="source">An <see cref="IBindableCollection{TSource}"/> to aggregate over.</param> /// <param name="func">An accumulator function to be invoked on each element.</param> /// <param name="dependencyAnalysisMode">The dependency analysis mode.</param> /// <returns>The final accumulator value.</returns> public static IBindable <TResult> Aggregate <TSource, TResult>(this IBindableCollection <TSource> source, Expression <Func <IBindableCollection <TSource>, TResult> > func, DependencyDiscovery dependencyAnalysisMode) { source.ShouldNotBeNull("source"); func.ShouldNotBeNull("func"); var result = new CustomAggregator <TSource, TResult>(source, func.Compile(), source.Dispatcher); if (dependencyAnalysisMode == DependencyDiscovery.Enabled) { return(result.DependsOnExpression(func, func.Parameters[0])); } return(result); }
/// <summary> /// Bindable LINQ: Filters a sequence of values based on a predicate. Each item will be re-evaluated if it raises a property changed event, or if any properties /// accessed in the filter expression raise events. Items will be re-evaluated when the source collection raises CollectionChanged events. The entire collection /// will be re-evaluated if the source collection raises a Reset event, or if any addtional dependencies added via the <see cref="WithDependencies{TResult}"/> /// extension method tell it to re-evaluate. /// </summary> /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam> /// <param name="source">An <see cref="IBindableCollection{TElement}"/> to filter.</param> /// <param name="predicate">A function to test each element for a condition.</param> /// <param name="dependencyAnalysisMode">The dependency analysis mode.</param> /// <returns> /// An <see cref="IBindableCollection{TElement}"/> that contains elements from the input sequence that satisfy the condition. /// </returns> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="source"/> or <paramref name="predicate"/> is null.</exception> public static IBindableCollection <TSource> Where <TSource>(this IBindableCollection <TSource> source, Expression <Func <TSource, bool> > predicate, DependencyDiscovery dependencyAnalysisMode) where TSource : class { source.ShouldNotBeNull("source"); predicate.ShouldNotBeNull("predicate"); var result = new WhereIterator <TSource>(source, predicate.Compile(), source.Dispatcher); if (dependencyAnalysisMode == DependencyDiscovery.Enabled) { return(result.DependsOnExpression(predicate.Body, predicate.Parameters[0])); } return(result); }
/// <summary> /// Groups the elements of a sequence according to a key selector function. The keys are compared by using a comparer and each group's elements are projected by using a specified function. /// </summary> /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam> /// <typeparam name="TKey">The type of the key returned by <paramref name="keySelector"/>.</typeparam> /// <typeparam name="TElement">The type of the elements in the <see cref="T:System.Linq.IGrouping`2"/>.</typeparam> /// <param name="source">An <see cref="IBindableCollection{TElement}"/> whose elements to group.</param> /// <param name="keySelector">A function to extract the key for each element.</param> /// <param name="elementSelector">A function to map each source element to an element in an <see cref="T:System.Linq.IGrouping`2"/>.</param> /// <param name="comparer">An <see cref="T:System.Collections.Generic.IEqualityComparer`1"/> to compare keys.</param> /// <param name="dependencyAnalysisMode">The dependency analysis mode.</param> /// <returns> /// An IEnumerable<IGrouping<TKey, TElement>> in C# or IEnumerable(Of IGrouping(Of TKey, TElement)) in Visual Basic where each <see cref="T:System.Linq.IGrouping`2"/> object contains a collection of objects of type TElement and a key. /// </returns> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="source"/> or <paramref name="keySelector"/> or <paramref name="elementSelector"/> is null.</exception> public static IBindableCollection <IBindableGrouping <TKey, TElement> > GroupBy <TSource, TKey, TElement>(this IBindableCollection <TSource> source, Expression <Func <TSource, TKey> > keySelector, Expression <Func <TSource, TElement> > elementSelector, IEqualityComparer <TKey> comparer, DependencyDiscovery dependencyAnalysisMode) where TSource : class where TElement : class { source.ShouldNotBeNull("source"); keySelector.ShouldNotBeNull("keySelector"); elementSelector.ShouldNotBeNull("elementSelector"); var result = new GroupByIterator <TKey, TSource, TElement>(source, keySelector, elementSelector, comparer, source.Dispatcher); if (dependencyAnalysisMode == DependencyDiscovery.Enabled) { return(result.DependsOnExpression(keySelector.Body, keySelector.Parameters[0])); } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="BindingListAdapter<TElement>"/> class. /// </summary> /// <param name="source">The source.</param> /// <param name="dispatcher">The dispatcher.</param> public BindingListAdapter(IBindableCollection <TElement> source, IDispatcher dispatcher) : base(dispatcher) { source.ShouldNotBeNull("source"); _originalSource = source; _eventHandler = Source_CollectionChanged; _weakHandler = new WeakEventProxy <NotifyCollectionChangedEventArgs>(_eventHandler); _sortDirection = ListSortDirection.Ascending; WireInterceptor(_originalSource); _propertyDescriptors = new Dictionary <string, PropertyDescriptor>(); var properties = TypeDescriptor.GetProperties(typeof(TElement)); foreach (PropertyDescriptor descriptor in properties) { if (descriptor != null && descriptor.Name != null) { _propertyDescriptors[descriptor.Name] = descriptor; } } }
/// <summary>Returns the first element of a sequence, or a default value if the sequence contains no elements.</summary> /// <returns>default(<typeparamref name="TSource" />) if <paramref name="source" /> is empty; otherwise, the first element in <paramref name="source" />.</returns> /// <param name="source">The <see cref="IBindableCollection{TElement}" /> to return the first element of.</param> /// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="source" /> is null.</exception> public static IBindable <TSource> FirstOrDefault <TSource>(this IBindableCollection <TSource> source) { source.ShouldNotBeNull("source"); return(source.ElementAtOrDefault(0)); }
private static IBindable <TAverageResult> AverageInternal <TResult, TAverageResult>(IBindableCollection <TResult> source, INumeric <TResult, TAverageResult> numeric) { source.ShouldNotBeNull("source"); return(Aggregate(source, sources => numeric.Average(sources))); }
private static IBindable <TElement> MinInternal <TElement, TAverage>(IBindableCollection <TElement> source, INumeric <TElement, TAverage> numeric) { source.ShouldNotBeNull("source"); return(Aggregate <TElement, TElement>(source, sources => numeric.Min(sources))); }
/// <summary>Invokes a transform function on each element of a sequence and returns the maximum <see cref="T:System.Single" /> value.</summary> /// <returns>The maximum value in the sequence.</returns> /// <param name="source">A sequence of values to determine the maximum value of.</param> /// <param name="selector">A transform function to apply to each element.</param> /// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="source" /> or <paramref name="selector" /> is null.</exception> /// <exception cref="T:System.InvalidOperationException"> /// <paramref name="source" /> contains no elements.</exception> public static IBindable <float> Max <TSource>(this IBindableCollection <TSource> source, Expression <Func <TSource, float> > selector) where TSource : class { source.ShouldNotBeNull("source"); return(source.Select(selector).Max()); }
/// <summary> /// Produces the set union of multiple sequences. /// </summary> /// <typeparam name="TSource">The type of the elements of the input sequences.</typeparam> /// <param name="sources">An <see cref="IBindableCollection{TElement}"/> whose elements are also <see cref="IBindableCollection{TElement}"/> of the elements to be combined.</param> /// <returns> /// An <see cref="IBindableCollection{TElement}"/> that contains the elements from both input sequences, excluding duplicates. /// </returns> /// <exception cref="T:System.ArgumentNullException"><paramref name="sources"/> is null.</exception> public static IBindableCollection <TSource> UnionAll <TSource>(this IBindableCollection <IBindableCollection <TSource> > sources) where TSource : class { sources.ShouldNotBeNull("sources"); return(new UnionIterator <TSource>(sources, sources.Dispatcher)); }
/// <summary> /// Determines whether any element of a sequence satisfies a condition. /// </summary> /// <param name="source">An <see cref="IBindableCollection{TElement}" /> whose elements to apply the predicate to.</param> /// <param name="predicate">A function to test each element for a condition.</param> /// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam> /// <returns>true if any elements in the source sequence pass the test in the specified predicate; otherwise, false.</returns> public static IBindable <bool> Any <TSource>(this IBindableCollection <TSource> source, Expression <Func <TSource, bool> > predicate) where TSource : class { source.ShouldNotBeNull("source"); predicate.ShouldNotBeNull("predicate"); return(source.Where(predicate).Any()); }
/// <summary>Returns the element at a specified index in a sequence or a default value if the index is out of range.</summary> /// <returns>default(<typeparamref name="TSource" />) if the index is outside the bounds of the source sequence; otherwise, the element at the specified position in the source sequence.</returns> /// <param name="source">An <see cref="IBindableCollection{TElement}" /> to return an element from.</param> /// <param name="index">The zero-based index of the element to retrieve.</param> /// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam> /// <exception cref="T:System.ArgumentNullException"> /// <paramref name="source" /> is null.</exception> public static IBindable <TSource> ElementAtOrDefault <TSource>(this IBindableCollection <TSource> source, int index) { source.ShouldNotBeNull("source"); return(new ElementAtAggregator <TSource>(source, index, source.Dispatcher)); }