V4 V5

Selection state belongs to the view. A Worksheet knows nothing about it.

B3:C7 selected, with B3 the active cell left white inside the range

Reading and moving

MemberWhat it is
control.SelectionThe selected range (RangePosition, read-only); the active area when there are several
control.SelectionAreasEvery selected area (IReadOnlyList<RangePosition>); the last entry is the active one
control.ActiveCellThe active cell (CellPosition, read-only)
control.MoveTo(row, col)Moves the active cell and collapses the selection to it
control.SelectionChangedRaised when the selection changes

Working with the viewport directly, it is viewport.Selection / viewport.ActiveCell / viewport.SetActiveCell(r, c) / viewport.ExtendSelectionTo(r, c) / viewport.SelectColumn(col).

using unvell.ReoGrid.Core;
using unvell.ReoGrid.Core.Rendering;

viewport.SetActiveCell(2, 1);              // make B3 active (the selection collapses to B3)
viewport.ExtendSelectionTo(6, 2);          // extend to B3:C7

RangePosition selection = viewport.Selection;
CellPosition active = viewport.ActiveCell;

viewport.SelectColumn(3);                  // the whole of column D
viewport.SelectRow(0);                     // the whole of row 1
viewport.SelectAll();

// whether whole rows or columns are selected is answerable without inspecting the range
bool wholeColumns = viewport.SelectionIsWholeColumns;

Multiple selection (non-contiguous areas)

Ctrl+click⌘+click on macOS — adds an area. As in Excel’s “multiple selection”, the selection is not one rectangle but a list of them.

GestureResult
Click / Ctrl+A / arrow keysCollapses back to one area
Ctrl (⌘) + click or dragAdds an area and makes it the active one
Ctrl (⌘) + click on a row / column headerAdds that whole row or column as an area
Shift+click / Shift+arrowExtends the active area only; the others stay

macOS takes ⌘ for more than convention’s sake: the OS turns Ctrl+click into a secondary click, so a Ctrl-only rule would fight the context menu. The command modifier (Ctrl on Windows and Linux, ⌘ on macOS) is the same one the cell editor and the Ctrl (⌘) + arrow data-edge jump already use.

The active cell always sits in the active area, and so does the fill handle.

using unvell.ReoGrid.Core;
using unvell.ReoGrid.Core.Rendering;

viewport.SetActiveCell(0, 0);              // A1
viewport.ExtendSelectionTo(2, 1);          // A1:B3 — the first area

viewport.AddSelectionArea(0, 4);           // open a second area at E1 (what Ctrl+click does)
viewport.ExtendSelectionTo(2, 5);          // extend it to E1:F3 — only the active area grows
viewport.AddColumnSelectionArea(7);        // the whole of column H as a third area

var areas = viewport.SelectionAreas;       // the last entry is the active area
bool many = viewport.HasMultipleAreas;
long cells = viewport.SelectionCellCount;
bool inside = viewport.SelectionContains(1, 5);   // in any area

// assigning collapses back to one area (what a plain click, a paste or a find hit does)
viewport.Selection = new RangePosition(0, 0, 1, 1);

Areas may overlap, and a bulk operation still touches a shared cell once: RangeSet.Disjoint normalizes the list into non-overlapping rectangles first, so a relative transform such as “increase indent by one” cannot apply twice.

Bulk operations on the selection

The control has a full set of helpers that act on the selection. Each one covers every selected area and folds them into a single Ctrl+Z. When whole rows or columns are selected they are routed to the row or column default style automatically, so nothing ever walks a million cells.

Formatting

Member
ToggleSelectionBold() / ToggleSelectionItalic() / ToggleSelectionUnderline()
SetSelectionTextColor(color) / SetSelectionBackColor(color)
SetSelectionFontFamily(family) / SetSelectionFontSize(size)
SetSelectionHAlign(align) / SetSelectionVAlign(align) / SetSelectionWrap(wrap)
SetSelectionNumberFormat(format)
MutateSelectionStyle(s => s with { ... }) — any transformation

Structure

Member
MergeSelection() / UnmergeSelection() — merging produces one merge per area, never one over their bounding box
SetSelectionOutline(color, width) / SetSelectionAllBorders(color, width) / ClearSelectionBorders()
InsertRowsAtSelection() / DeleteSelectedRows()
InsertColumnsAtSelection() / DeleteSelectedColumns()
SetSelectedRowHeight(h) / SetSelectedColumnWidth(w)
AutoFitSelectedColumns() / AutoFitSelectedRows()
SetSelectionCellType(type)

Clipboard

CopySelection() / CutSelection() / PasteClipboard()

The clipboard is a rectangle, so copying several areas only goes through when they pack into one block — either they share their columns and stack vertically, or they share their rows and sit side by side. Anything else is refused with the same sentence Excel uses. See Clipboard.

Why the model does not hold the selection

V4 kept it on the model as worksheet.SelectionRange. V5 separates them so that showing one worksheet through several views, and running headless, are both straightforward.

As a consequence, the selection is not saved to a file.

Keyboard

Arrow keys, Shift+arrow to extend, Ctrl+arrow to jump, Home / End and Page Up / Down are wired up by default.

viewport.StepTarget(dRow, dCol) only computes where a move would land, which is useful when implementing your own key bindings.

Was this article helpful?