GridX Selection System
Pluggable ISelectionStrategy with 6 strategies — Cell, Row, MultiCell, MultiRow, Column — Ctrl/Shift modifier handling, SelectionContext state bag, and keyboard navigation
Table of Contents
Overview
Namespace: TheTechIdea.Beep.Winform.Controls.GridX.Selection
The grid selection system uses the Strategy pattern with 6 implementations of ISelectionStrategy (all internal sealed, all singletons via public static readonly ... Instance). Each strategy handles cell clicks, column-header clicks, keyboard navigation, and selection clearing independently. The active strategy is selected by the grid's SelectionMode property.
All strategies receive a SelectionContext object that provides grid state access and a StrategyState dictionary for storing strategy-specific data (e.g., anchor position for range selection in MultiCellStrategy).
ISelectionStrategy Interface
internal interface ISelectionStrategy
{
void HandleCellClick(SelectionContext context,
int row, int col, bool ctrlPressed, bool shiftPressed);
void HandleColumnHeaderClick(SelectionContext context,
int col, bool ctrlPressed, bool shiftPressed);
void HandleKeyboardNavigation(SelectionContext context,
int deltaRow, int deltaCol);
void ClearSelection(SelectionContext context);
}SelectionContext
Lightweight context object passed to every strategy method. Thread-unsafe — designed for single UI thread use only.
| Member | Type | Description |
|---|---|---|
| Grid | BeepGridPro | The grid instance |
| Selection | GridSelectionHelper | Helper for state manipulation (SelectCell, SelectRow) |
| StrategyState | Dictionary<string,object> | Bag for strategy-specific data (anchors, ranges, last-selected) |
| RowCount | int | Current rows from Grid.Data.Rows.Count |
| ColumnCount | int | Current columns from Grid.Data.Columns.Count |
| IsValidCell(r,c) | bool | Boundary check: 0 ≤ row < RowCount, 0 ≤ col < ColumnCount |
| SetActiveCell(r,c) | void | Sets active cell via Selection.SelectCell(row, col) |
| SetRowSelected(r, bool) | void | Sets Data.Rows[row].IsSelected |
| SetCellSelected(r,c, bool) | void | Sets per-cell IsSelected on the data cell |
| ClearAllRowSelection() | void | Iterates all rows: IsSelected = false |
| ClearAllCellSelection() | void | Iterates all cells: IsSelected = false |
| RaiseRowSelectionChanged(r) | void | Fires the grid's row selection changed event |
| EnsureVisible() | void | Scrolls to active cell's row/column |
CellSelectionStrategy
Single cell selection. public static readonly CellSelectionStrategy Instance.
- HandleCellClick: Clears all cell AND row selection, then selects only the clicked cell via SetActiveCell
- HandleColumnHeaderClick: No-op (column headers ignored)
- HandleKeyboardNavigation: Moves single cell by (deltaRow, deltaCol), clamped to grid bounds via IsValidCell
- ClearSelection: Clears all row and cell selection state
RowSelectionStrategy
Full row selection. public static readonly RowSelectionStrategy Instance.
- HandleCellClick: When Ctrl is pressed AND
Grid.MultiSelectis true, toggles the clicked row's selection (additive). Otherwise clears all and selects the entire row (all columns marked selected). - HandleColumnHeaderClick: No-op
- HandleKeyboardNavigation: Moves to next/previous row (deltaRow). Keeps the column index from
Selection.ColumnIndexso the active cell stays in the same column. - ClearSelection: Clears all row and cell selection
MultiCellSelectionStrategy
Excel-style multi-cell with range selection. public static readonly MultiCellSelectionStrategy Instance. Uses StrategyState["MultiCellAnchor"] to store anchor (int Row, int Col).
- HandleCellClick (Ctrl): Toggles the individual cell selection without clearing existing selection. Updates anchor.
- HandleCellClick (Shift): Selects a rectangular range from the anchor (row1,col1) to the clicked cell (row2,col2). All cells in the rectangle are selected.
- HandleCellClick (normal): Clears all, selects only the clicked cell, sets anchor.
- HandleColumnHeaderClick (normal): Clears all, selects all cells in the target column.
- HandleColumnHeaderClick (Ctrl/Shift): Adds the column's cells to existing selection.
- HandleKeyboardNavigation: Moves single-cell selection, clears others, updates anchor.
- Private helpers:
ClearAndSelect,SetAnchor(row,col)stores tuple in StrategyState,GetAnchorretrieves(int Row, int Col)?.
MultiRowSelectionStrategy
Multi-row with Shift+range expansion from anchor. Same structure as RowSelectionStrategy but Shift+click selects a continuous row range from anchor to clicked row. Ctrl+click toggles individual rows.
ColumnSelectionStrategy
Column-level selection. Clicking a column header selects all cells in that column. Shift+click expands to a contiguous column range. Ctrl+click modifies the column selection (adds/removes column).
Comparison Table
| Strategy | Normal Click | Ctrl+Click | Shift+Click | Column Click | Keyboard |
|---|---|---|---|---|---|
| Cell | Select cell | Select cell | Select cell | None | Move cell |
| Row | Select row | Toggle row | Select row | None | Move row |
| MultiCell | Select cell | Toggle cell | Range from anchor | Select column | Move cell |
| MultiRow | Select row | Toggle row | Row range | None | Move row |
| Column | Select cell | Select cell | Select cell | Select column | Move cell |
Code Examples
// Cell selection (default)
grid.SelectionMode = BeepGridSelectionMode.Cell; // CellSelectionStrategy
// Full row selection
grid.SelectionMode = BeepGridSelectionMode.FullRow; // RowSelectionStrategy
grid.MultiSelect = true; // Ctrl+click toggles rows
// Excel-style multi-cell
grid.SelectionMode = BeepGridSelectionMode.MultiCell; // MultiCellSelectionStrategy
// Now: Shift+drag for rectangular range, Ctrl+click for individual cells