diff --git a/ClosedXML/Excel/Ranges/IXLRanges.cs b/ClosedXML/Excel/Ranges/IXLRanges.cs
index cadda81..815f6f0 100644
--- a/ClosedXML/Excel/Ranges/IXLRanges.cs
+++ b/ClosedXML/Excel/Ranges/IXLRanges.cs
@@ -20,10 +20,13 @@
void Remove(IXLRange range);
///
- /// Removes all ranges from the collection optionally disposing them.
+ /// Removes ranges matching the criteria from the collection, optionally releasing their event handlers.
///
- ///
- void RemoveAll(bool dispose = true);
+ /// Criteria to filter ranges. Only those ranges that satisfy the criteria will be removed.
+ /// Null means the entire collection should be cleared.
+ /// Specify whether or not should removed ranges be unsubscribed from
+ /// row/column shifting events. Until ranges are unsubscribed they cannot be collected by GC.
+ void RemoveAll(Predicate match = null, bool releaseEventHandlers = true);
Int32 Count { get; }
diff --git a/ClosedXML/Excel/Ranges/XLRanges.cs b/ClosedXML/Excel/Ranges/XLRanges.cs
index 9a5c9b4..3b0650e 100644
--- a/ClosedXML/Excel/Ranges/XLRanges.cs
+++ b/ClosedXML/Excel/Ranges/XLRanges.cs
@@ -47,12 +47,25 @@
_ranges.RemoveAll(r => r.ToString() == range.ToString());
}
- public void RemoveAll(bool dispose = true)
+ ///
+ /// Removes ranges matching the criteria from the collection, optionally releasing their event handlers.
+ ///
+ /// Criteria to filter ranges. Only those ranges that satisfy the criteria will be removed.
+ /// Null means the entire collection should be cleared.
+ /// Specify whether or not should removed ranges be unsubscribed from
+ /// row/column shifting events. Until ranges are unsubscribed they cannot be collected by GC.
+ public void RemoveAll(Predicate match = null, bool releaseEventHandlers = true)
{
- Count = 0;
- if (dispose)
- _ranges.ForEach(r => r.Dispose());
- _ranges.Clear();
+ match = match ?? (_ => true);
+
+ if (releaseEventHandlers)
+ {
+ _ranges
+ .Where(r => match(r))
+ .ForEach(r => r.Dispose());
+ }
+
+ Count -= _ranges.RemoveAll(match);
}
public int Count { get; private set; }
diff --git a/ClosedXML_Tests/Excel/Ranges/XLRangeBaseTests.cs b/ClosedXML_Tests/Excel/Ranges/XLRangeBaseTests.cs
index 8171db0..5668d01 100644
--- a/ClosedXML_Tests/Excel/Ranges/XLRangeBaseTests.cs
+++ b/ClosedXML_Tests/Excel/Ranges/XLRangeBaseTests.cs
@@ -415,7 +415,7 @@
ranges.Add(ws.Range("B1:B2"));
var rangesCopy = ranges.ToList();
- ranges.RemoveAll(false);
+ ranges.RemoveAll(null, false);
ws.FirstColumn().InsertColumnsBefore(1);
Assert.AreEqual(0, ranges.Count);
@@ -423,5 +423,22 @@
Assert.AreEqual("B1:B2", rangesCopy.First().RangeAddress.ToString());
Assert.AreEqual("C1:C2", rangesCopy.Last().RangeAddress.ToString());
}
+
+
+ [Test]
+ public void RangesRemoveAllByCriteria()
+ {
+ var ws = new XLWorkbook().Worksheets.Add("Sheet1");
+ var ranges = new XLRanges();
+ ranges.Add(ws.Range("A1:A2"));
+ ranges.Add(ws.Range("B1:B3"));
+ ranges.Add(ws.Range("C1:C4"));
+ var otherRange = ws.Range("A3:D3");
+
+ ranges.RemoveAll(r => r.Intersects(otherRange));
+
+ Assert.AreEqual(1, ranges.Count);
+ Assert.AreEqual("A1:A2", ranges.Single().RangeAddress.ToString());
+ }
}
}