Table of Contents

Selection

TableView supports selecting individual cells, whole rows, or a combination of both. You control the selection behavior through SelectionMode and SelectionUnit.

When to use it

  • Use row selection for list-style UIs where you act on entire records.
  • Use cell selection for spreadsheet-style UIs where you need to reference or copy individual values.
  • Use combined modes for data grids where users can do both.

SelectionMode

SelectionMode inherits from ListViewSelectionMode and controls how many rows (or cells) can be selected at once:

Value Description
None Selection is disabled
Single Only one row/cell can be selected at a time
Multiple Multiple items can be selected individually
Extended (default) Click to select; Shift+Click to range-select; Ctrl+Click to toggle
<tv:TableView SelectionMode="Single" />

SelectionUnit

SelectionUnit determines what the user can select:

Value Description
CellOrRow (default) Clicking a cell selects that cell; clicking a row header selects the row. Cell selection and row selection are independent.
CellWithRow Clicking a cell selects the cell and also selects the owning row.
Cell Only cells can be selected; row headers do not select rows.
Row Only rows can be selected; clicking a cell selects the row.
<tv:TableView SelectionUnit="Row" SelectionMode="Single" />

Cell selection in action

Reading selected items

For row selection, use the standard ListView properties:

// Single selected item
var item = tableView.SelectedItem as Product;

// Multiple selected items
foreach (var item in tableView.SelectedItems.OfType<Product>())
{
    // ...
}

For cell selection, use SelectedCells or listen to CellSelectionChanged:

tableView.CellSelectionChanged += (s, e) =>
{
    foreach (var slot in e.AddedCells)
    {
        int row = slot.Row;
        int col = slot.Column;
        Console.WriteLine($"Selected cell ({row}, {col})");
    }

    foreach (var slot in e.RemovedCells)
    {
        Console.WriteLine($"Deselected cell ({row}, {col})");
    }
};

TableViewCellSlot

A TableViewCellSlot is a lightweight record struct that identifies a cell by its row and column indices:

public readonly record struct TableViewCellSlot(int Row, int Column);
// Navigate to a specific cell
tableView.CurrentCellSlot = new TableViewCellSlot(2, 1);

CurrentCellSlot

CurrentCellSlot is a nullable dependency property that identifies the currently focused cell:

var current = tableView.CurrentCellSlot;
if (current.HasValue)
{
    Console.WriteLine($"Current cell: row {current.Value.Row}, column {current.Value.Column}");
}

Handle CurrentCellChanged to react when focus moves to a different cell:

tableView.CurrentCellChanged += (s, e) =>
{
    var slot = tableView.CurrentCellSlot;
};

Corner button

The corner button appears in the top-left cell above the row headers. Its behavior is controlled by the CornerButtonMode property.

<tv:TableView CornerButtonMode="Options" />

CornerButtonMode values

Value Description
None No corner button is shown
SelectAll Shows a Select All checkbox/button that selects all rows
Options (default) Shows a table-level options menu (flyout)

Options flyout

When CornerButtonMode is Options (the default), clicking the corner button opens a flyout menu with the following commands:

Menu item Description
Select All Selects all rows
Deselect All Clears all selections
Copy Copies selected rows/cells to clipboard (Ctrl+C)
Copy with Headers Copies selection with column headers (Ctrl+Shift+C)
Paste Pastes clipboard content into the table (Ctrl+V)
Clear Sorting Removes all active sort descriptions
Clear Filter Removes all active column filters
Export All to CSV Exports all rows to a CSV file
Export Selected to CSV Exports only the selected rows to a CSV file

Items are automatically disabled when not applicable — for example, Paste is hidden when CanPaste is false, and the Export items are only visible when ShowExportOptions is true.

<!-- Disable the corner button entirely -->
<tv:TableView CornerButtonMode="None" />

<!-- Show only a Select All button (no flyout) -->
<tv:TableView CornerButtonMode="SelectAll" />

<!-- Show the full Options flyout (default) -->
<tv:TableView CornerButtonMode="Options" />

ForceRowOrCellSelectionOnContextRequested

When showing a context menu, you may want to ensure the right-clicked row or cell becomes selected. Set this property to true:

<tv:TableView ForceRowOrCellSelectionOnContextRequested="True" />

Cell selection changed event

tableView.CellSelectionChanged += (s, e) =>
{
    // e.AddedCells: newly selected cells
    // e.RemovedCells: newly deselected cells
};

Notes and limitations

  • When SelectionUnit is Row, the SelectedCells collection and CellSelectionChanged are not used.
  • Drag selection is supported for cell selection. The selection rectangle is shown by default; disable it with ShowDragRectangle = false.
  • In CellOrRow mode, row and cell selections are tracked independently. A selected row does not mean its cells are in SelectedCells.