Initial commit of the ClosedXML library

Establishes the foundational structure, core Excel functionality, and tooling.

- Implements base components for cells, ranges, columns, and rows.
- Integrates a custom calculation engine with a wide range of Excel functions.
- Adds comprehensive support for styling, conditional formatting, data validation, comments, pictures, and charts.
- Configures build setup, project metadata (NuGet), and developer guidelines.
- Includes editor and Git attributes for consistent code style and line endings.
This commit is contained in:
Thom Lamb
2026-06-23 11:02:53 -05:00
parent 28bc05cf54
commit 2cd6df6481
1092 changed files with 97270 additions and 408 deletions
@@ -0,0 +1,127 @@
using ClosedXML.Excel;
using NUnit.Framework;
using System.Linq;
namespace ClosedXML_Tests.Excel.DataValidations
{
[TestFixture]
public class DataValidationShiftTests
{
[Test]
public void DataValidationShiftedOnColumnInsert()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet("DataValidationShift");
ws.Range("A1:A1").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("A2:B2").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("A3:C3").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("B4:B6").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("C7:D7").SetDataValidation().WholeNumber.Between(0, 1);
ws.Cells("A1:D7").Value = 1;
ws.Column(2).InsertColumnsAfter(2);
var dv = ws.DataValidations.ToArray();
Assert.AreEqual(5, dv.Length);
Assert.AreEqual("A1:A1", dv[0].Ranges.Single().RangeAddress.ToString());
Assert.AreEqual("A2:D2", dv[1].Ranges.Single().RangeAddress.ToString());
Assert.AreEqual("A3:E3", dv[2].Ranges.Single().RangeAddress.ToString());
Assert.AreEqual("B4:D6", dv[3].Ranges.Single().RangeAddress.ToString());
Assert.AreEqual("E7:F7", dv[4].Ranges.Single().RangeAddress.ToString());
}
}
[Test]
public void DataValidationShiftedOnRowInsert()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet("DataValidationShift");
ws.Range("A1:A1").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("B1:B2").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("C1:C3").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("D2:F2").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("G4:G5").SetDataValidation().WholeNumber.Between(0, 1);
ws.Cells("A1:G5").Value = 1;
ws.Row(2).InsertRowsBelow(2);
var dv = ws.DataValidations.ToArray();
Assert.AreEqual(5, dv.Length);
Assert.AreEqual("A1:A1", dv[0].Ranges.Single().RangeAddress.ToString());
Assert.AreEqual("B1:B4", dv[1].Ranges.Single().RangeAddress.ToString());
Assert.AreEqual("C1:C5", dv[2].Ranges.Single().RangeAddress.ToString());
Assert.AreEqual("D2:F4", dv[3].Ranges.Single().RangeAddress.ToString());
Assert.AreEqual("G6:G7", dv[4].Ranges.Single().RangeAddress.ToString());
}
}
[Test]
public void DataValidationShiftedOnColumnDelete()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet("DataValidationShift");
ws.Range("A1:A1").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("A2:B2").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("A3:C3").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("B4:B6").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("C7:D7").SetDataValidation().WholeNumber.Between(0, 1);
ws.Cells("A1:D7").Value = 1;
ws.Column(2).Delete();
var dv = ws.DataValidations.ToArray();
Assert.AreEqual(4, dv.Length);
Assert.AreEqual("A1:A1", dv[0].Ranges.Single().RangeAddress.ToString());
Assert.AreEqual("A2:A2", dv[1].Ranges.Single().RangeAddress.ToString());
Assert.AreEqual("A3:B3", dv[2].Ranges.Single().RangeAddress.ToString());
Assert.AreEqual("B7:C7", dv[3].Ranges.Single().RangeAddress.ToString());
}
}
[Test]
public void DataValidationShiftedOnRowDelete()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet("DataValidationShift");
ws.Range("A1:A1").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("B1:B2").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("C1:C3").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("D2:F2").SetDataValidation().WholeNumber.Between(0, 1);
ws.Range("G4:G5").SetDataValidation().WholeNumber.Between(0, 1);
ws.Cells("A1:G5").Value = 1;
ws.Row(2).Delete();
var dv = ws.DataValidations.ToArray();
Assert.AreEqual(4, dv.Length);
Assert.AreEqual("A1:A1", dv[0].Ranges.Single().RangeAddress.ToString());
Assert.AreEqual("B1:B1", dv[1].Ranges.Single().RangeAddress.ToString());
Assert.AreEqual("C1:C2", dv[2].Ranges.Single().RangeAddress.ToString());
Assert.AreEqual("G3:G4", dv[3].Ranges.Single().RangeAddress.ToString());
}
}
[Test]
public void DataValidationShiftedTruncateRange()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet("DataValidationShift");
ws.AsRange().SetDataValidation().WholeNumber.Between(0, 1);
var dv = ws.DataValidations.Single();
ws.Row(2).InsertRowsAbove(1);
Assert.IsTrue(dv.Ranges.Single().RangeAddress.IsValid);
Assert.AreEqual($"1:{XLHelper.MaxRowNumber}", dv.Ranges.Single().RangeAddress.ToString());
ws.Column(2).InsertColumnsAfter(1);
Assert.IsTrue(dv.Ranges.Single().RangeAddress.IsValid);
Assert.AreEqual($"1:{XLHelper.MaxRowNumber}", dv.Ranges.Single().RangeAddress.ToString());
}
}
}
}
@@ -0,0 +1,483 @@
using ClosedXML.Excel;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ClosedXML_Tests.Excel.DataValidations
{
[TestFixture]
public class DataValidationTests
{
[Test]
public void Validation_1()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.Worksheets.Add("Data Validation Issue");
IXLCell cell = ws.Cell("E1");
cell.SetValue("Value 1");
cell = cell.CellBelow();
cell.SetValue("Value 2");
cell = cell.CellBelow();
cell.SetValue("Value 3");
cell = cell.CellBelow();
cell.SetValue("Value 4");
ws.Cell("A1").SetValue("Cell below has Validation Only.");
cell = ws.Cell("A2");
cell.DataValidation.List(ws.Range("$E$1:$E$4"));
ws.Cell("B1").SetValue("Cell below has Validation with a title.");
cell = ws.Cell("B2");
cell.DataValidation.List(ws.Range("$E$1:$E$4"));
cell.DataValidation.InputTitle = "Title for B2";
Assert.AreEqual(XLAllowedValues.List, cell.DataValidation.AllowedValues);
Assert.AreEqual("'Data Validation Issue'!$E$1:$E$4", cell.DataValidation.Value);
Assert.AreEqual("Title for B2", cell.DataValidation.InputTitle);
ws.Cell("C1").SetValue("Cell below has Validation with a message.");
cell = ws.Cell("C2");
cell.DataValidation.List(ws.Range("$E$1:$E$4"));
cell.DataValidation.InputMessage = "Message for C2";
Assert.AreEqual(XLAllowedValues.List, cell.DataValidation.AllowedValues);
Assert.AreEqual("'Data Validation Issue'!$E$1:$E$4", cell.DataValidation.Value);
Assert.AreEqual("Message for C2", cell.DataValidation.InputMessage);
ws.Cell("D1").SetValue("Cell below has Validation with title and message.");
cell = ws.Cell("D2");
cell.DataValidation.List(ws.Range("$E$1:$E$4"));
cell.DataValidation.InputTitle = "Title for D2";
cell.DataValidation.InputMessage = "Message for D2";
Assert.AreEqual(XLAllowedValues.List, cell.DataValidation.AllowedValues);
Assert.AreEqual("'Data Validation Issue'!$E$1:$E$4", cell.DataValidation.Value);
Assert.AreEqual("Title for D2", cell.DataValidation.InputTitle);
Assert.AreEqual("Message for D2", cell.DataValidation.InputMessage);
}
[Test]
public void Validation_2()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
ws.Cell("A1").SetValue("A");
ws.Cell("B1").SetDataValidation().Custom("Sheet1!A1");
IXLWorksheet ws2 = wb.AddWorksheet("Sheet2");
ws2.Cell("A1").SetValue("B");
ws.Cell("B1").CopyTo(ws2.Cell("B1"));
Assert.AreEqual("Sheet1!A1", ws2.Cell("B1").DataValidation.Value);
}
[Test, Ignore("Wait for proper formula shifting (#686)")]
public void Validation_3()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
ws.Cell("A1").SetValue("A");
ws.Cell("B1").SetDataValidation().Custom("A1");
ws.FirstRow().InsertRowsAbove(1);
Assert.AreEqual("A2", ws.Cell("B2").DataValidation.Value);
}
[Test]
public void Validation_4()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
ws.Cell("A1").SetValue("A");
ws.Cell("B1").SetDataValidation().Custom("A1");
ws.Cell("B1").CopyTo(ws.Cell("B2"));
Assert.AreEqual("A2", ws.Cell("B2").DataValidation.Value);
}
[Test, Ignore("Wait for proper formula shifting (#686)")]
public void Validation_5()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
ws.Cell("A1").SetValue("A");
ws.Cell("B1").SetDataValidation().Custom("A1");
ws.FirstColumn().InsertColumnsBefore(1);
Assert.AreEqual("B1", ws.Cell("C1").DataValidation.Value);
}
[Test]
public void Validation_6()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.Worksheets.Add("Sheet1");
ws.Cell("A1").SetValue("A");
ws.Cell("B1").SetDataValidation().Custom("A1");
ws.Cell("B1").CopyTo(ws.Cell("C1"));
Assert.AreEqual("B1", ws.Cell("C1").DataValidation.Value);
}
[Test]
public void Validation_persists_on_Cell_DataValidation()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.Worksheets.Add("People");
ws.FirstCell().SetValue("Categories")
.CellBelow().SetValue("A")
.CellBelow().SetValue("B");
IXLTable table = ws.RangeUsed().CreateTable();
IXLDataValidation dv = table.DataRange.SetDataValidation();
dv.ErrorTitle = "Error";
Assert.AreEqual("Error", table.DataRange.FirstCell().DataValidation.ErrorTitle);
}
[Test]
public void Validation_persists_on_Worksheet_DataValidations()
{
var wb = new XLWorkbook();
IXLWorksheet ws = wb.Worksheets.Add("People");
ws.FirstCell().SetValue("Categories")
.CellBelow().SetValue("A");
IXLTable table = ws.RangeUsed().CreateTable();
IXLDataValidation dv = table.DataRange.SetDataValidation();
dv.ErrorTitle = "Error";
Assert.AreEqual("Error", ws.DataValidations.Single().ErrorTitle);
}
[Test]
[TestCase("A1:C3", 5, false, "A1:C3")]
[TestCase("A1:C3", 2, false, "A1:C4")]
[TestCase("A1:C3", 1, false, "A2:C4")]
[TestCase("A1:C3", 5, true, "A1:C3")]
[TestCase("A1:C3", 2, true, "A1:C4")]
[TestCase("A1:C3", 1, true, "A2:C4")]
public void DataValidationShiftedOnRowInsert(string initialAddress, int rowNum, bool setValue, string expectedAddress)
{
//Arrange
var wb = new XLWorkbook();
var ws = wb.Worksheets.Add("DataValidation");
var validation = ws.Range(initialAddress).SetDataValidation();
validation.WholeNumber.Between(0, 100);
if (setValue)
ws.Range(initialAddress).Value = 50;
//Act
ws.Row(rowNum).InsertRowsAbove(1);
//Assert
Assert.AreEqual(1, ws.DataValidations.Count());
Assert.AreEqual(1, ws.DataValidations.First().Ranges.Count());
Assert.AreEqual(expectedAddress, ws.DataValidations.First().Ranges.First().RangeAddress.ToString());
}
[Test]
[TestCase("A1:C3", 5, false, "A1:C3")]
[TestCase("A1:C3", 2, false, "A1:D3")]
[TestCase("A1:C3", 1, false, "B1:D3")]
[TestCase("A1:C3", 5, true, "A1:C3")]
[TestCase("A1:C3", 2, true, "A1:D3")]
[TestCase("A1:C3", 1, true, "B1:D3")]
public void DataValidationShiftedOnColumnInsert(string initialAddress, int columnNum, bool setValue, string expectedAddress)
{
//Arrange
var wb = new XLWorkbook();
var ws = wb.Worksheets.Add("DataValidation");
var validation = ws.Range(initialAddress).SetDataValidation();
validation.WholeNumber.Between(0, 100);
if (setValue)
ws.Range(initialAddress).Value = 50;
//Act
ws.Column(columnNum).InsertColumnsBefore(1);
//Assert
Assert.AreEqual(1, ws.DataValidations.Count());
Assert.AreEqual(1, ws.DataValidations.First().Ranges.Count());
Assert.AreEqual(expectedAddress, ws.DataValidations.First().Ranges.First().RangeAddress.ToString());
}
[Test]
public void DataValidationClearSplitsRange()
{
using (var wb = new XLWorkbook())
{
var ws = wb.Worksheets.Add("DataValidation");
var validation = ws.Range("A1:C3").SetDataValidation();
validation.WholeNumber.Between(0, 100);
//Act
ws.Cell("B2").Clear(XLClearOptions.DataValidation);
//Assert
Assert.IsFalse(ws.Cell("B2").HasDataValidation);
Assert.IsTrue(ws.Range("A1:C3").Cells().Where(c => c.Address.ToString() != "B2").All(c => c.HasDataValidation));
}
}
[Test]
public void NewDataValidationSplitsRange()
{
using (var wb = new XLWorkbook())
{
var ws = wb.Worksheets.Add("DataValidation");
var validation = ws.Range("A1:C3").SetDataValidation();
validation.WholeNumber.Between(10, 100);
//Act
ws.Cell("B2").NewDataValidation.WholeNumber.Between(-100, -0);
//Assert
Assert.AreEqual("-100", ws.Cell("B2").DataValidation.MinValue);
Assert.IsTrue(ws.Range("A1:C3").Cells().Where(c => c.Address.ToString() != "B2").All(c => c.HasDataValidation));
Assert.IsTrue(ws.Range("A1:C3").Cells().Where(c => c.Address.ToString() != "B2")
.All(c => c.DataValidation.MinValue == "10"));
}
}
[Test]
public void ListLengthOverflow()
{
var values = string.Join(",", Enumerable.Range(1, 20)
.Select(i => Guid.NewGuid().ToString("N")));
Assert.True(values.Length > 255);
using (var wb = new XLWorkbook())
{
var dv = wb.AddWorksheet("Sheet 1").Cell(1, 1).DataValidation;
Assert.Throws<ArgumentOutOfRangeException>(() => dv.List(values));
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
dv.TextLength.Between(0, 5);
dv.MinValue = values;
});
Assert.Throws<ArgumentOutOfRangeException>(() =>
{
dv.TextLength.Between(0, 5);
dv.MaxValue = values;
});
}
}
[Test]
public void CannotCreateDataValidationWithoutRange()
{
Assert.Throws<ArgumentNullException>(() => new XLDataValidation(null));
}
[Test]
public void DataValidationHasWorksheetAndRangesWhenCreated()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var range = ws.Range("A1:A3");
var dv = new XLDataValidation(range);
Assert.AreSame(ws, dv.Worksheet);
Assert.AreSame(range, dv.Ranges.Single());
}
}
[Test]
public void CanAddRangeFromSameWorksheet()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var range1 = ws.Range("A1:A3");
var range2 = ws.Range("C1:C3");
var ranges3 = ws.Ranges("D1:D3,F1:F3");
var dv = new XLDataValidation(range1);
dv.AddRange(range2);
dv.AddRanges(ranges3);
Assert.IsTrue(dv.Ranges.Any(r => r == range1));
Assert.IsTrue(dv.Ranges.Any(r => r == range2));
Assert.IsTrue(dv.Ranges.Any(r => r == ranges3.First()));
Assert.IsTrue(dv.Ranges.Any(r => r == ranges3.Last()));
}
}
[Test]
public void CanAddRangeFromAnotherWorksheet()
{
using (var wb = new XLWorkbook())
{
var ws1 = wb.AddWorksheet();
var ws2 = wb.AddWorksheet();
var range1 = ws1.Range("A1:A3");
var range2 = ws2.Range("C1:C3");
var dv = new XLDataValidation(range1);
dv.AddRange(range2);
Assert.IsTrue(dv.Ranges.Any(r => r != range2 && r.RangeAddress.ToString() == range2.RangeAddress.ToString()));
}
}
[Test]
public void CanClearRanges()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var range1 = ws.Range("A1:A3");
var range2 = ws.Range("C1:C3");
var ranges3 = ws.Ranges("D1:D3,F1:F3");
var dv = new XLDataValidation(range1);
dv.AddRange(range2);
dv.AddRanges(ranges3);
dv.ClearRanges();
Assert.IsEmpty(dv.Ranges);
}
}
[Test]
public void CanRemoveExistingRange()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var range1 = ws.Range("A1:A3");
var range2 = ws.Range("C1:C3");
var dv = new XLDataValidation(range1);
dv.AddRange(range2);
dv.RemoveRange(range1);
Assert.AreSame(range2, dv.Ranges.Single());
}
}
[Test]
public void RemovingExistingRangeDoesNoFail()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var range1 = ws.Range("A1:A3");
var range2 = ws.Range("C1:C3");
var dv = new XLDataValidation(range1);
dv.RemoveRange(range2);
dv.RemoveRange(null);
Assert.AreSame(range1, dv.Ranges.Single());
}
}
[Test]
public void AddRangeFiresEvent()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var range1 = ws.Range("A1:A3");
var range2 = ws.Range("C1:C3");
var dv = new XLDataValidation(range1);
IXLRange addedRange = null;
dv.RangeAdded += (s, e) => addedRange = e.Range;
dv.AddRange(range2);
Assert.AreSame(range2, addedRange);
}
}
[Test]
public void AddRangesFiresMultipleEvents()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var range1 = ws.Range("A1:A3");
var ranges = ws.Ranges("D1:D3,F1:F3");
var dv = new XLDataValidation(range1);
var addedRanges = new List<IXLRange>();
dv.RangeAdded += (s, e) => addedRanges.Add(e.Range);
dv.AddRanges(ranges);
Assert.AreEqual(2, addedRanges.Count);
}
}
[Test]
public void RemoveRangeFiresEvent()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var range1 = ws.Range("A1:A3");
var range2 = ws.Range("C1:C3");
var dv = new XLDataValidation(range1);
dv.AddRange(range2);
IXLRange removedRange = null;
dv.RangeRemoved += (s, e) => removedRange = e.Range;
dv.RemoveRange(range2);
Assert.AreSame(range2, removedRange);
}
}
[Test]
public void RemoveNonExistingRangeDoesNotFireEvent()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var range1 = ws.Range("A1:A3");
var range2 = ws.Range("C1:C3");
var dv = new XLDataValidation(range1);
dv.RangeRemoved += (s, e) => Assert.Fail("Expected not to fire event");
dv.RemoveRange(range2);
}
}
[Test]
public void ClearRangesFiresMultipleEvents()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var range1 = ws.Range("A1:A3");
var range2 = ws.Range("C1:C3");
var dv = new XLDataValidation(range1);
dv.AddRange(range2);
var removedRanges = new List<IXLRange>();
dv.RangeRemoved += (s, e) => removedRanges.Add(e.Range);
dv.ClearRanges();
Assert.AreEqual(2, removedRanges.Count);
}
}
}
}
@@ -0,0 +1,154 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ClosedXML.Excel;
using NUnit.Framework;
namespace ClosedXML_Tests.Excel.DataValidations
{
public class XLDataValidationsTests
{
[Test]
public void CannotCreateWithoutWorksheet()
{
Assert.Throws<ArgumentNullException>(() => new XLDataValidations(null));
}
[Test]
public void AddedRangesAreTransferredToTargetSheet()
{
using (var wb = new XLWorkbook())
{
var ws1 = wb.AddWorksheet();
var ws2 = wb.AddWorksheet();
var dv1 = ws1.Range("A1:A3").SetDataValidation();
dv1.MinValue = "100";
var dv2 = ws2.DataValidations.Add(dv1);
Assert.AreEqual(1, ws1.DataValidations.Count());
Assert.AreEqual(1, ws2.DataValidations.Count());
Assert.AreNotSame(dv1, dv2);
Assert.AreSame(ws1, dv1.Ranges.Single().Worksheet);
Assert.AreSame(ws2, dv2.Ranges.Single().Worksheet);
}
}
[TestCase("A1:A1", true)]
[TestCase("A1:A3", true)]
[TestCase("A1:A4", false)]
[TestCase("C2:C2", true)]
[TestCase("C1:C3", true)]
[TestCase("A1:C3", false)]
public void CanFindDataValidationForRange(string searchAddress, bool expectedResult)
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var dv = ws.Range("A1:A3").SetDataValidation();
dv.MinValue = "100";
dv.AddRange(ws.Range("C1:C3"));
var address = new XLRangeAddress(ws as XLWorksheet, searchAddress);
var actualResult = ws.DataValidations.TryGet(address, out var foundDv);
Assert.AreEqual(expectedResult, actualResult);
if (expectedResult)
Assert.AreSame(dv, foundDv);
else
Assert.IsNull(foundDv);
}
}
[TestCase("A1:A1", 1)]
[TestCase("A1:A3", 1)]
[TestCase("B1:B4", 0)]
[TestCase("A1:C3", 1)]
[TestCase("C2:C3", 1)]
[TestCase("C2:G6", 2)]
[TestCase("E2:E3", 0)]
public void CanGetAllDataValidationsForRange(string searchAddress, int expectedCount)
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var dv1 = ws.Range("A1:A3").SetDataValidation();
dv1.MinValue = "100";
dv1.AddRange(ws.Range("C1:C3"));
var dv2 = ws.Range("E4:G6").SetDataValidation();
dv2.MinValue = "200";
var address = new XLRangeAddress(ws as XLWorksheet, searchAddress);
var actualResult = ws.DataValidations.GetAllInRange(address);
Assert.AreEqual(expectedCount, actualResult.Count());
}
}
[Test]
public void AddDataValidationSplitsExistingRanges()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var dv1 = ws.Ranges("B2:G7,C11:C13").SetDataValidation();
dv1.MinValue = "100";
var dv2 = ws.Range("E4:G6").SetDataValidation();
dv2.MinValue = "100";
Assert.AreEqual(4, dv1.Ranges.Count());
Assert.AreEqual("B2:G3,B4:D6,B7:G7,C11:C13",
string.Join(",", dv1.Ranges.Select(r => r.RangeAddress.ToString())));
}
}
[Test]
public void RemovedRangeExcludedFromIndex()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var dv = ws.Range("A1:A3").SetDataValidation();
dv.MinValue = "100";
var range = ws.Range("C1:C3");
dv.AddRange(range);
dv.RemoveRange(range);
var actualResult = ws.DataValidations.TryGet(range.RangeAddress, out var foundDv);
Assert.IsFalse(actualResult);
Assert.IsNull(foundDv);
}
}
[Test]
public void ConsolidatedDataValidationsAreUnsubscribed()
{
using (var wb = new XLWorkbook())
{
var ws = wb.AddWorksheet();
var dv1 = ws.Range("A1:A3").SetDataValidation();
dv1.MinValue = "100";
var dv2 = ws.Range("B1:B3").SetDataValidation();
dv2.MinValue = "100";
(ws.DataValidations as XLDataValidations).Consolidate();
dv1.AddRange(ws.Range("C1:C3"));
dv2.AddRange(ws.Range("D1:D3"));
var consolidatedDv = ws.DataValidations.Single();
Assert.AreSame(dv1, consolidatedDv);
Assert.True(ws.Cell("C1").HasDataValidation);
Assert.False(ws.Cell("D1").HasDataValidation);
}
}
}
}