/// <summary> /// Check are there any merged range exist in specified range /// </summary> /// <param name="range">range to be checked</param> /// <returns>the intersected range with specified range</returns> public RangePosition CheckIntersectedMergingRange(RangePosition range) { RangePosition intersectedRange = RangePosition.Empty; cells.Iterate(range.Row, range.Col, range.Rows, range.Cols, true, (r, c, cell) => { if (!cell.MergeStartPos.IsEmpty) { Cell checkStartCell = GetCell(cell.MergeStartPos); for (int rr = checkStartCell.InternalRow; rr <= checkStartCell.MergeEndPos.Row; rr++) { for (int cc = checkStartCell.InternalCol; cc <= checkStartCell.MergeEndPos.Col; cc++) { var targetCell = cells[rr, cc]; if (targetCell != null && !range.Contains(targetCell.InternalPos)) { intersectedRange = new RangePosition(checkStartCell.InternalPos, checkStartCell.MergeEndPos); break; } } if (!intersectedRange.IsEmpty) { break; } } return(intersectedRange.IsEmpty ? 0 : cell.Colspan); } return(cell.Colspan < 1 ? 1 : cell.Colspan); }); return(intersectedRange); }
internal void MergeRange(RangePosition range, bool checkIntersection = true, bool updateUIAndEvent = true) { if (range.IsEmpty) { return; } RangePosition fixedRange = FixRange(range); if (fixedRange.Cols <= 1 && fixedRange.Rows <= 1) { return; } if (checkIntersection) { RangePosition intersectedRange = CheckIntersectedMergingRange(fixedRange); if (!intersectedRange.IsEmpty) { throw new RangeIntersectionException(intersectedRange); } } int row = fixedRange.Row; int col = fixedRange.Col; int torow = fixedRange.EndRow; int tocol = fixedRange.EndCol; // find start and end cell Cell startCell = cells[row, col]; Cell endCell = cells[torow, tocol]; if (startCell == null) { startCell = CreateCell(row, col); } if (endCell == null) { endCell = CreateCell(torow, tocol); } for (int r = row; r <= torow; r++) { for (int c = col; c <= tocol; c++) { Cell cell = CreateAndGetCell(r, c); // reference to start and end pos cell.MergeStartPos = startCell.InternalPos; cell.MergeEndPos = endCell.InternalPos; // close col and row span cell.Colspan = 0; cell.Rowspan = 0; // apply text to merged start cell if (cell != startCell) { cell.InnerData = cell.InnerDisplay = null; } if (r == row) { if (c > col) { CutBeforeVBorder(r, c); } } else { hBorders[r, c] = new ReoGridHBorder { Span = 0 }; } if (c == col) { if (r > row) { CutBeforeHBorder(r, c); } } else { vBorders[r, c] = new ReoGridVBorder { Span = 0 }; } } } // update the spans for start cell startCell.Rowspan = (short)fixedRange.Rows; startCell.Colspan = (short)fixedRange.Cols; // fix selection if (this.selectionRange.IntersectWith(fixedRange)) { this.selectionRange = this.CheckMergedRange(fixedRange); } // fix focus pos if (fixedRange.Contains(this.focusPos)) { this.focusPos = fixedRange.StartPos; } if (updateUIAndEvent) { RequestInvalidate(); if (RangeMerged != null) { RangeMerged(this, new RangeEventArgs(fixedRange)); } } }