跳到主要内容

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 of 0 as it is the first item at the root of the hierarchy
  • B has an index path of 0,0 as it is the first child of the first item
  • C has an index path of 0,1 as it is the second child of the first item
  • D has an index path of 0,1,0 as it is the first child of C
  • E has an index path of 1 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");
};