Selection
Two selection modes are supported:
- Row selection allows the user to select whole rows
- Cell selection allows the user to select individual cells
Both selection types support either single or multiple selection. The default selection type is single row selection.
Index Paths
Because TreeDataGrid
supports hierarchical data, using a simple index to identify a row in the data source isn't enough. Instead indexes are represented using the IndexPath
struct.
An IndexPath
is an array of indexes, each element of which specifies the index at a successively deeper level in the hierarchy of the data.
Consider the following data source:
|- A
| |- B
| |- C
| |- D
|- E
A
has an index path of0
as it is the first item at the root of the hierarchyB
has an index path of0,0
as it is the first child of the first itemC
has an index path of0,1
as it is the second child of the first itemD
has an index path of0,1,0
as it is the first child ofC
E
has an index path of1
as it is the second item in the root
IndexPath
is an immutable struct which is constructed with an array of integers, e.g.: new IndexPath(0, 1, 0)
. There is also an implicit conversion from int
for when working with a flat data source.
Row Selection
Row selection is the default and is exposed via the RowSelection
property on the source.
Row selection is stored in an instance of the TreeDataGridRowSelectionModel<TModel>
class.
The default is single selection. To enable multiple selection set the the SingleSelect
property to false
, e.g.:
Source = new FlatTreeDataGridSource<Person>(_people)
{
Columns =
{
new TextColumn<Person, string>("First Name", x => x.FirstName),
new TextColumn<Person, string>("Last Name", x => x.LastName),
new TextColumn<Person, int>("Age", x => x.Age),
},
};
Source.RowSelection!.SingleSelect = false;
Getting Selected Items
Access selected items through the selection model:
// Get single selected item
if (Source.RowSelection?.SelectedItem is Person selectedPerson)
{
Debug.WriteLine($"Selected: {selectedPerson.Name}");
}
// Get multiple selected items
var selectedItems = Source.RowSelection?.SelectedItems;
if (selectedItems != null)
{
foreach (var item in selectedItems.OfType<Person>())
{
Debug.WriteLine($"Selected: {item.Name}");
}
}
Programmatically Selecting Rows
You can select rows programmatically using the selection model:
var selection = Source.RowSelection;
// Select by index
selection.SelectedIndex = 2;
selection.SelectedIndex = new IndexPath(2);
selection.SelectedIndex = new IndexPath(2, 1);
// Clear selection
selection.Clear();
// Select multiple items
selection.Select(2);
selection.Select(new IndexPath(2, 1));
// Deselect multiple items
selection.Deselect(2);
selection.Deselect(new IndexPath(2, 1));
// Batch selection changes
selection.BeginBatchUpdate();
selection.Select(0);
selection.Select(1);
selection.Deselect(2);
selection.EndBatchUpdate();
Selection Changed Event
Handle selection changes with the SelectionChanged
event:
Source.RowSelection.SelectionChanged += (sender, e) =>
{
Debug.WriteLine($"Selection changed");
Debug.WriteLine($"Added: {e.SelectedItems.Count}");
Debug.WriteLine($"Removed: {e.DeselectedItems.Count}");
};
Cell Selection
To enable cell selection for a TreeDataGrid source, assign an instance of TreeDataGridCellSelectionModel<TModel>
to the source's Selection
property:
Source = new FlatTreeDataGridSource<Person>(_people)
{
Columns =
{
new TextColumn<Person, string>("First Name", x => x.FirstName),
new TextColumn<Person, string>("Last Name", x => x.LastName),
new TextColumn<Person, int>("Age", x => x.Age),
},
};
Source.Selection = new TreeDataGridCellSelectionModel<Person>(Source);
When multiple cell selection is enabled, a single rectangular range of cells can be selected:
Source.Selection = new TreeDataGridCellSelectionModel<Person>(Source)
{
SingleSelect = false
};
Cell selection is exposed via the CellSelection
property on the source.
The CellIndex
struct identifies an individual cell by a combination of an integer column index and an IndexPath
row index:
// Access selected cell
if (Source.CellSelection?.SelectedIndex is { } selectedCell)
{
Debug.WriteLine($"Selected cell - Row: {selectedCell.RowIndex}, Column: {selectedCell.ColumnIndex}");
}
Getting Selected Items
Access selected items through the selection model:
// Get single selected cell
var selection = Source.CellSelection!;
if (selection.SelectedIndex.ColumnIndex != -1 &&
selection.SelectedIndex.RowIndex.Count == 1)
{
var column = Source.Columns[selection.SelectedIndex.ColumnIndex];
var model = _data[selection.SelectedIndex.RowIndex[0]];
Debug.WriteLine("Selected column: " + column.Header);
Debug.WriteLine("Selected item: " + model);
}
// Get multiple selected cells
var selection = Source.CellSelection!;
foreach (var selected in selection.SelectedIndexes)
{
if (selected.ColumnIndex != -1 && selected.RowIndex.Count == 1)
{
var column = Source.Columns[selected.ColumnIndex];
var model = _data[selected.RowIndex[0]];
Debug.WriteLine("Selected column: " + column.Header);
Debug.WriteLine("Selected item: " + model);
}
}
Programmatically Selecting Cells
You can select cells programmatically using the selection model:
var selection = Source.CellSelection;
// Select by index
selection.SelectedIndex = new CellIndex(2, 1);
selection.SelectedIndex = new CellIndex(3, new IndexPath(2));
// Select a range
selection.SetSelectedRange(new CellIndex(1, 1), columnCount: 2, rowCount: 2);
Selection Changed Event
Handle selection changes with the SelectionChanged
event:
Source.CellSelection!.SelectionChanged += (s, e) =>
{
Debug.WriteLine($"Selection changed");
};