diff --git a/MvvmHelpers.Tests/MvvmHelpers.Tests.csproj b/MvvmHelpers.Tests/MvvmHelpers.Tests.csproj
index eef8627..b5ede74 100644
--- a/MvvmHelpers.Tests/MvvmHelpers.Tests.csproj
+++ b/MvvmHelpers.Tests/MvvmHelpers.Tests.csproj
@@ -1,4 +1,4 @@
-
+
Debug
@@ -46,4 +46,7 @@
MvvmHelpers
+
+
+
\ No newline at end of file
diff --git a/MvvmHelpers.Tests/ObservableRangeTests.cs b/MvvmHelpers.Tests/ObservableRangeTests.cs
index 119ad18..63b3f2b 100644
--- a/MvvmHelpers.Tests/ObservableRangeTests.cs
+++ b/MvvmHelpers.Tests/ObservableRangeTests.cs
@@ -33,10 +33,35 @@ public void GroupingTestCase()
orderby person.LastName
group person by person.SortName into personGroup
select new Grouping(personGroup.Key, personGroup);
-
+
grouped.AddRange(sorted);
}
+
+ [Test()]
+ public void RemoveRange_RemoveTest()
+ {
+ ObservableRangeCollection collection = new ObservableRangeCollection();
+ int[] toAdd = new[] { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2, 3 };
+ int[] toRemove = new[] { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 0, 0 };
+ collection.AddRange(toAdd);
+ collection.CollectionChanged += (s, e) =>
+ {
+ if (e.Action != System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
+ Assert.Fail("RemoveRange didn't use Remove like requested.");
+ if (e.OldItems == null)
+ Assert.Fail("OldItems should not be null.");
+ int[] expected = new int[] { 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9, 9 };
+ if (expected.Length != e.OldItems.Count)
+ Assert.Fail("Expected and actual OldItems don't match.");
+ for (int i = 0; i < expected.Length; i++)
+ {
+ if (expected[i] != (int)e.OldItems[i])
+ Assert.Fail("Expected and actual OldItems don't match.");
+ }
+ };
+ collection.RemoveRange(toRemove, System.Collections.Specialized.NotifyCollectionChangedAction.Remove);
+ }
}
}
diff --git a/MvvmHelpers/ObservableRangeCollection.cs b/MvvmHelpers/ObservableRangeCollection.cs
index 1c13d45..5932363 100644
--- a/MvvmHelpers/ObservableRangeCollection.cs
+++ b/MvvmHelpers/ObservableRangeCollection.cs
@@ -37,6 +37,8 @@ public ObservableRangeCollection(IEnumerable collection)
///
public void AddRange(IEnumerable collection, NotifyCollectionChangedAction notificationMode = NotifyCollectionChangedAction.Add)
{
+ if (notificationMode != NotifyCollectionChangedAction.Add && notificationMode != NotifyCollectionChangedAction.Reset)
+ throw new ArgumentException("Mode must be either Add or Reset for AddRange.", "notificationMode");
if (collection == null)
throw new ArgumentNullException("collection");
@@ -69,16 +71,40 @@ public void AddRange(IEnumerable collection, NotifyCollectionChangedAction no
}
///
- /// Removes the first occurence of each item in the specified collection from ObservableCollection(Of T).
+ /// Removes the first occurence of each item in the specified collection from ObservableCollection(Of T). NOTE: with notificationMode = Remove, removed items starting index is not set because items are not guaranteed to be consecutive.
///
- public void RemoveRange(IEnumerable collection)
+ public void RemoveRange(IEnumerable collection, NotifyCollectionChangedAction notificationMode = NotifyCollectionChangedAction.Reset)
{
+ if (notificationMode != NotifyCollectionChangedAction.Remove && notificationMode != NotifyCollectionChangedAction.Reset)
+ throw new ArgumentException("Mode must be either Remove or Reset for RemoveRange.", "notificationMode");
if (collection == null)
throw new ArgumentNullException("collection");
- foreach (var i in collection)
- Items.Remove(i);
- OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
+ CheckReentrancy();
+
+ if (notificationMode == NotifyCollectionChangedAction.Reset)
+ {
+
+ foreach (var i in collection)
+ Items.Remove(i);
+ OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
+
+ return;
+ }
+
+ var changedItems = collection is List ? (List)collection : new List(collection);
+ for (int i = 0; i < changedItems.Count; i++)
+ {
+ if (!Items.Remove(changedItems[i]))
+ {
+ changedItems.RemoveAt(i); //Can't use a foreach because changedItems is intended to be (carefully) modified
+ i--;
+ }
+ }
+
+ OnPropertyChanged(new PropertyChangedEventArgs("Count"));
+ OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
+ OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, changedItems, -1));
}
///