Files
radzen-blazor/Radzen.Blazor/Spreadsheet/MergeCellsCommand.cs
Atanas Korchev 4f28ea704a Introduce RangeSnapshotCommandBase for per-cell undo snapshots
Five commands (Sort, MultiKeySort, MergeCells, ClearContents, Autofill)
reinvented the same Dictionary<CellRef, (value, formula, format)>
snapshot+restore plumbing with subtly different correctness:

- SortCommand and MultiKeySortCommand blindly wrote both Value AND
  Formula on undo, silently clobbering formulas. Fixed by routing
  through the base class's 'formula ?? value' restore.

- MergeCellsCommand and AutofillCommand never cleared the snapshot
  before Execute, accumulating stale entries across redo cycles.
  Fixed by the base clearing in its template Execute.

Also adds AutofillCommand named epsilon constants (NumericStepEpsilon
and DateStepEpsilonInDays) replacing the unexplained 1e-10 vs 0.001
inconsistency in DetectSeries.
2026-06-15 18:45:16 +03:00

74 lines
1.7 KiB
C#

using Radzen.Documents.Spreadsheet;
namespace Radzen.Blazor.Spreadsheet;
#nullable enable
/// <summary>
/// Command to merge a range of cells.
/// </summary>
public class MergeCellsCommand : RangeSnapshotCommandBase
{
/// <inheritdoc/>
public override SheetAction RequiredAction => SheetAction.FormatCells;
/// <inheritdoc/>
public override SpreadsheetFeature? Feature => SpreadsheetFeature.Merging;
private readonly RangeRef range;
private readonly bool center;
/// <summary>
/// Initializes a new instance of the <see cref="MergeCellsCommand"/> class.
/// </summary>
public MergeCellsCommand(Worksheet sheet, RangeRef range, bool center = false)
: base(sheet)
{
this.range = range;
this.center = center;
}
/// <inheritdoc/>
protected override bool DoExecute()
{
if (range.Start == range.End)
{
return false;
}
var overlapping = sheet.MergedCells.GetOverlappingRanges(range);
if (overlapping.Count > 0)
{
return false;
}
foreach (var cellRef in range.GetCells())
{
Capture(cellRef);
if (cellRef != range.Start)
{
var cell = sheet.Cells[cellRef.Row, cellRef.Column];
cell.Value = null;
}
}
sheet.MergedCells.Add(range);
if (center)
{
var topLeft = sheet.Cells[range.Start.Row, range.Start.Column];
topLeft.Format = topLeft.Format.WithTextAlign(TextAlign.Center);
}
return true;
}
/// <inheritdoc/>
public override void Unexecute()
{
sheet.MergedCells.Remove(range);
RestoreSnapshot();
}
}