33using System . Collections . Specialized ;
44using System . Diagnostics ;
55using System . Diagnostics . Contracts ;
6+ using System . Linq ;
67using System . Reactive ;
8+ using System . Reactive . Concurrency ;
79using System . Reactive . Disposables ;
810using System . Reactive . Linq ;
9- using System . Reactive . Subjects ;
1011using System . Runtime . CompilerServices ;
1112using System . Threading ;
1213using Splat ;
13- using System . Reactive . Concurrency ;
14- using System . Linq ;
1514
1615namespace ReactiveUI
1716{
@@ -425,7 +424,7 @@ void onSourceCollectionChanged(NotifyCollectionChangedEventArgs args)
425424 }
426425
427426 // Yeah apparently this can happen. ObservableCollection triggers this notification on Move(0,0)
428- if ( args . OldStartingIndex == args . NewStartingIndex ) {
427+ if ( args . OldStartingIndex == args . NewStartingIndex ) {
429428 return ;
430429 }
431430
@@ -445,7 +444,7 @@ void onSourceCollectionChanged(NotifyCollectionChangedEventArgs args)
445444
446445 TValue value = base [ currentDestinationIndex ] ;
447446
448- if ( orderer == null ) {
447+ if ( orderer == null ) {
449448 // We mirror the order of the source collection so we'll perform the same move operation
450449 // as the source. As is the case with when we have an orderer we don't test whether or not
451450 // the item should be included or not here. If it has been included at some point it'll
@@ -582,7 +581,7 @@ protected override void internalClear()
582581 indexToSourceIndexMap . Clear ( ) ;
583582 sourceCopy . Clear ( ) ;
584583 var items = this . ToArray ( ) ;
585-
584+
586585 base . internalClear ( ) ;
587586
588587 foreach ( var item in items ) { onRemoved ( item ) ; }
@@ -698,7 +697,7 @@ internal static int newPositionForExistingItem<T>(
698697
699698 Debug . Assert ( list . Count > 0 ) ;
700699
701- if ( list . Count == 1 ) {
700+ if ( list . Count == 1 ) {
702701 return 0 ;
703702 }
704703
@@ -708,7 +707,7 @@ internal static int newPositionForExistingItem<T>(
708707 // The item on the preceding or succeeding index relative to currentIndex.
709708 T comparand = list [ precedingIndex >= 0 ? precedingIndex : succeedingIndex ] ;
710709
711- if ( orderer == null ) {
710+ if ( orderer == null ) {
712711 orderer = Comparer < T > . Default . Compare ;
713712 }
714713
@@ -718,10 +717,10 @@ internal static int newPositionForExistingItem<T>(
718717 int min = 0 ;
719718 int max = list . Count ;
720719
721- if ( cmp == 0 ) {
720+ if ( cmp == 0 ) {
722721 // The new value is equal to the preceding or succeeding item, it may stay at the current position
723722 return currentIndex ;
724- } else if ( cmp > 0 ) {
723+ } else if ( cmp > 0 ) {
725724 // The new value is greater than the preceding or succeeding item, limit the search to indices after
726725 // the succeeding item.
727726 min = succeedingIndex ;
@@ -754,7 +753,7 @@ public override void Dispose(bool disposing)
754753 }
755754 }
756755
757- internal class ReactiveDerivedCollectionFromObservable < T > : ReactiveDerivedCollection < T >
756+ internal class ReactiveDerivedCollectionFromObservable < T > : ReactiveDerivedCollection < T >
758757 {
759758 SingleAssignmentDisposable inner ;
760759
@@ -777,7 +776,7 @@ public ReactiveDerivedCollectionFromObservable(
777776 var queue = new Queue < T > ( ) ;
778777 var disconnect = Observable . Timer ( withDelay . Value , withDelay . Value , scheduler )
779778 . Subscribe ( _ => {
780- if ( queue . Count > 0 ) {
779+ if ( queue . Count > 0 ) {
781780 this . internalAdd ( queue . Dequeue ( ) ) ;
782781 }
783782 } ) ;
@@ -792,7 +791,7 @@ public ReactiveDerivedCollectionFromObservable(
792791 // Observable. Combine the two values, and when they're equal,
793792 // disconnect the timer
794793 this . ItemsAdded . Scan ( 0 , ( ( acc , _ ) => acc + 1 ) ) . Zip ( observable . Aggregate ( 0 , ( acc , _ ) => acc + 1 ) ,
795- ( l , r ) => ( l == r ) ) . Where ( x => x ) . Subscribe ( _ => disconnect . Dispose ( ) ) ;
794+ ( l , r ) => ( l == r ) ) . Where ( x => x ) . Subscribe ( _ => disconnect . Dispose ( ) ) ;
796795 }
797796
798797 public override void Dispose ( bool disposing )
@@ -806,19 +805,26 @@ public override void Dispose(bool disposing)
806805 }
807806 }
808807
808+ /// <summary>
809+ /// Extension methods to create collections from observables
810+ /// </summary>
809811 public static class ReactiveCollectionMixins
810812 {
811813 /// <summary>
812814 /// Creates a collection based on an an Observable by adding items
813815 /// provided until the Observable completes. This method guarantees that
814816 /// items are always added in the context of the provided scheduler.
815817 /// </summary>
816- /// <param name="fromObservable">The Observable whose items will be put
817- /// into the new collection.</param>
818- /// <param name="scheduler">Optionally specifies the scheduler on which
819- /// the collection will be populated. Defaults to the main scheduler.</param>
820- /// <returns>A new collection which will be populated with the
821- /// Observable.</returns>
818+ /// <param name="fromObservable">
819+ /// The Observable whose items will be put into the new collection.
820+ /// </param>
821+ /// <param name="scheduler">
822+ /// Optionally specifies the scheduler on which
823+ /// the collection will be populated. Defaults to the main scheduler.
824+ /// </param>
825+ /// <returns>
826+ /// A new collection which will be populated with the Observable.
827+ /// </returns>
822828 public static IReactiveDerivedList < T > CreateCollection < T > (
823829 this IObservable < T > fromObservable ,
824830 IScheduler scheduler )
@@ -833,18 +839,25 @@ public static IReactiveDerivedList<T> CreateCollection<T>(
833839 /// set, this method will leak a Timer. This method also guarantees that
834840 /// items are always added in the context of the provided scheduler.
835841 /// </summary>
836- /// <param name="fromObservable">The Observable whose items will be put
837- /// into the new collection.</param>
838- /// <param name="onError">The handler for errors from the Observable. If
839- /// not specified, an error will go to DefaultExceptionHandler.</param>
840- /// <param name="withDelay">If set, items will be populated in the
841- /// collection no faster than the delay provided.</param>
842- /// <param name="scheduler">Optionally specifies the scheduler on which
843- /// the collection will be populated. Defaults to the main scheduler.</param>
844- /// <returns>A new collection which will be populated with the
845- /// Observable.</returns>
842+ /// <param name="fromObservable">
843+ /// The Observable whose items will be put into the new collection.
844+ /// </param>
845+ /// <param name="onError">
846+ /// The handler for errors from the Observable. If not specified,
847+ /// an error will go to DefaultExceptionHandler.
848+ /// </param>
849+ /// <param name="withDelay">
850+ /// If set, items will be populated in the collection no faster than the delay provided.
851+ /// </param>
852+ /// <param name="scheduler">
853+ /// Optionally specifies the scheduler on which the collection will be populated.
854+ /// Defaults to the main scheduler.
855+ /// </param>
856+ /// <returns>
857+ /// A new collection which will be populated with the Observable.
858+ /// </returns>
846859 public static IReactiveDerivedList < T > CreateCollection < T > (
847- this IObservable < T > fromObservable ,
860+ this IObservable < T > fromObservable ,
848861 TimeSpan ? withDelay = null ,
849862 Action < Exception > onError = null ,
850863 IScheduler scheduler = null )
@@ -853,6 +866,9 @@ public static IReactiveDerivedList<T> CreateCollection<T>(
853866 }
854867 }
855868
869+ /// <summary>
870+ /// Extension methods to create collections that "follow" other collections.
871+ /// </summary>
856872 public static class ObservableCollectionMixin
857873 {
858874 /// <summary>
@@ -863,24 +879,37 @@ public static class ObservableCollectionMixin
863879 ///
864880 /// Note that even though this method attaches itself to any
865881 /// IEnumerable, it will only detect changes from objects implementing
866- /// INotifyCollectionChanged (like ReactiveList). If your source
867- /// collection doesn't implement this, signalReset is the way to signal
868- /// the derived collection to reorder/refilter itself.
882+ /// <see cref=" INotifyCollectionChanged"/> (like <see cref=" ReactiveList{T}"/> ).
883+ /// If your source collection doesn't implement this, <paramref name=" signalReset"/>
884+ /// is the way to signal the derived collection to reorder/refilter itself.
869885 /// </summary>
870- /// <param name="selector">A Select function that will be run on each
871- /// item.</param>
872- /// <param name="onRemoved">An action that is called on each item when
873- /// it is removed.</param>
874- /// <param name="filter">A filter to determine whether to exclude items
875- /// in the derived collection.</param>
876- /// <param name="orderer">A comparator method to determine the ordering of
877- /// the resulting collection.</param>
878- /// <param name="signalReset">When this Observable is signalled,
879- /// the derived collection will be manually
880- /// reordered/refiltered.</param>
881- /// <returns>A new collection whose items are equivalent to
882- /// Collection.Select().Where().OrderBy() and will mirror changes
883- /// in the initial collection.</returns>
886+ /// <param name="This">
887+ /// The source <see cref="IEnumerable{T}"/> to track.
888+ /// </param>
889+ /// <param name="selector">
890+ /// A Select function that will be run on each item.
891+ /// </param>
892+ /// <param name="onRemoved">
893+ /// An action that is called on each item when it is removed.
894+ /// </param>
895+ /// <param name="filter">
896+ /// A filter to determine whether to exclude items in the derived collection.
897+ /// </param>
898+ /// <param name="orderer">
899+ /// A comparator method to determine the ordering of the resulting collection.
900+ /// </param>
901+ /// <param name="signalReset">
902+ /// When this Observable is signalled, the derived collection will be manually
903+ /// reordered/refiltered.
904+ /// </param>
905+ /// <param name="scheduler">
906+ /// An optional scheduler used to dispatch change notifications.
907+ /// </param>
908+ /// <returns>
909+ /// A new collection whose items are equivalent to
910+ /// <c>Collection.Select().Where().OrderBy()</c> and will mirror changes
911+ /// in the initial collection.
912+ /// </returns>
884913 public static IReactiveDerivedList < TNew > CreateDerivedCollection < T , TNew , TDontCare > (
885914 this IEnumerable < T > This ,
886915 Func < T , TNew > selector ,
@@ -913,22 +942,34 @@ public static IReactiveDerivedList<TNew> CreateDerivedCollection<T, TNew, TDontC
913942 ///
914943 /// Note that even though this method attaches itself to any
915944 /// IEnumerable, it will only detect changes from objects implementing
916- /// INotifyCollectionChanged (like ReactiveList). If your source
917- /// collection doesn't implement this, signalReset is the way to signal
918- /// the derived collection to reorder/refilter itself.
945+ /// <see cref=" INotifyCollectionChanged"/> (like <see cref=" ReactiveList{T}"/> ).
946+ /// If your source collection doesn't implement this, <paramref name=" signalReset"/>
947+ /// is the way to signal the derived collection to reorder/refilter itself.
919948 /// </summary>
920- /// <param name="selector">A Select function that will be run on each
921- /// item.</param>
922- /// <param name="filter">A filter to determine whether to exclude items
923- /// in the derived collection.</param>
924- /// <param name="orderer">A comparator method to determine the ordering of
925- /// the resulting collection.</param>
926- /// <param name="signalReset">When this Observable is signalled,
927- /// the derived collection will be manually
928- /// reordered/refiltered.</param>
929- /// <returns>A new collection whose items are equivalent to
930- /// Collection.Select().Where().OrderBy() and will mirror changes
931- /// in the initial collection.</returns>
949+ /// <param name="This">
950+ /// The source <see cref="IEnumerable{T}"/> to track.
951+ /// </param>
952+ /// <param name="selector">
953+ /// A Select function that will be run on each item.
954+ /// </param>
955+ /// <param name="filter">
956+ /// A filter to determine whether to exclude items in the derived collection.
957+ /// </param>
958+ /// <param name="orderer">
959+ /// A comparator method to determine the ordering of the resulting collection.
960+ /// </param>
961+ /// <param name="signalReset">
962+ /// When this Observable is signalled, the derived collection will be manually
963+ /// reordered/refiltered.
964+ /// </param>
965+ /// <param name="scheduler">
966+ /// An optional scheduler used to dispatch change notifications.
967+ /// </param>
968+ /// <returns>
969+ /// A new collection whose items are equivalent to
970+ /// <c>Collection.Select().Where().OrderBy()</c> and will mirror changes
971+ /// in the initial collection.
972+ /// </returns>
932973 public static IReactiveDerivedList < TNew > CreateDerivedCollection < T , TNew , TDontCare > (
933974 this IEnumerable < T > This ,
934975 Func < T , TNew > selector ,
@@ -945,23 +986,35 @@ public static IReactiveDerivedList<TNew> CreateDerivedCollection<T, TNew, TDontC
945986 /// collection; this method is useful for creating ViewModel collections
946987 /// that are automatically updated when the respective Model collection
947988 /// is updated.
948- ///
989+ ///
949990 /// Be aware that this overload will result in a collection that *only*
950991 /// updates if the source implements INotifyCollectionChanged. If your
951992 /// list changes but isn't a ReactiveList/ObservableCollection,
952993 /// you probably want to use the other overload.
953994 /// </summary>
954- /// <param name="selector">A Select function that will be run on each
955- /// item.</param>
956- /// <param name="onRemoved">An action that is called on each item when
957- /// it is removed.</param>
958- /// <param name="filter">A filter to determine whether to exclude items
959- /// in the derived collection.</param>
960- /// <param name="orderer">A comparator method to determine the ordering of
961- /// the resulting collection.</param>
962- /// <returns>A new collection whose items are equivalent to
963- /// Collection.Select().Where().OrderBy() and will mirror changes
964- /// in the initial collection.</returns>
995+ /// <param name="This">
996+ /// The source <see cref="IEnumerable{T}"/> to track.
997+ /// </param>
998+ /// <param name="selector">
999+ /// A Select function that will be run on each item.
1000+ /// </param>
1001+ /// <param name="onRemoved">
1002+ /// An action that is called on each item when it is removed.
1003+ /// </param>
1004+ /// <param name="filter">
1005+ /// A filter to determine whether to exclude items in the derived collection.
1006+ /// </param>
1007+ /// <param name="orderer">
1008+ /// A comparator method to determine the ordering of the resulting collection.
1009+ /// </param>
1010+ /// <param name="scheduler">
1011+ /// An optional scheduler used to dispatch change notifications.
1012+ /// </param>
1013+ /// <returns>
1014+ /// A new collection whose items are equivalent to
1015+ /// <c>Collection.Select().Where().OrderBy()</c> and will mirror changes
1016+ /// in the initial collection.
1017+ /// </returns>
9651018 public static IReactiveDerivedList < TNew > CreateDerivedCollection < T , TNew > (
9661019 this IEnumerable < T > This ,
9671020 Func < T , TNew > selector ,
@@ -978,21 +1031,32 @@ public static IReactiveDerivedList<TNew> CreateDerivedCollection<T, TNew>(
9781031 /// collection; this method is useful for creating ViewModel collections
9791032 /// that are automatically updated when the respective Model collection
9801033 /// is updated.
981- ///
1034+ ///
9821035 /// Be aware that this overload will result in a collection that *only*
9831036 /// updates if the source implements INotifyCollectionChanged. If your
9841037 /// list changes but isn't a ReactiveList/ObservableCollection,
9851038 /// you probably want to use the other overload.
9861039 /// </summary>
987- /// <param name="selector">A Select function that will be run on each
988- /// item.</param>
989- /// <param name="filter">A filter to determine whether to exclude items
990- /// in the derived collection.</param>
991- /// <param name="orderer">A comparator method to determine the ordering of
992- /// the resulting collection.</param>
993- /// <returns>A new collection whose items are equivalent to
994- /// Collection.Select().Where().OrderBy() and will mirror changes
995- /// in the initial collection.</returns>
1040+ /// <param name="This">
1041+ /// The source <see cref="IEnumerable{T}"/> to track.
1042+ /// </param>
1043+ /// <param name="selector">
1044+ /// A Select function that will be run on each item.
1045+ /// </param>
1046+ /// <param name="filter">
1047+ /// A filter to determine whether to exclude items in the derived collection.
1048+ /// </param>
1049+ /// <param name="orderer">
1050+ /// A comparator method to determine the ordering of the resulting collection.
1051+ /// </param>
1052+ /// <param name="scheduler">
1053+ /// An optional scheduler used to dispatch change notifications.
1054+ /// </param>
1055+ /// <returns>
1056+ /// A new collection whose items are equivalent to
1057+ /// <c>Collection.Select().Where().OrderBy()</c> and will mirror changes
1058+ /// in the initial collection.
1059+ /// </returns>
9961060 public static IReactiveDerivedList < TNew > CreateDerivedCollection < T , TNew > (
9971061 this IEnumerable < T > This ,
9981062 Func < T , TNew > selector ,
0 commit comments