|
| 1 | +--- |
| 2 | +title: Cell Selection |
| 3 | +page_title: Grid - Cells Selection |
| 4 | +description: Learn how to select cell in Blazor Grid component. Explore the selected cells. Discover cell selection bevahior when combined with other Grid features. Try the practical sample code for cell selection. |
| 5 | +slug: grid-selection-cell |
| 6 | +tags: telerik,blazor,grid,selection,cells |
| 7 | +position: 5 |
| 8 | +--- |
| 9 | + |
| 10 | +# Cell Selection |
| 11 | + |
| 12 | +The Grid component supports [single or multiple cell selection]({%slug grid-selection-overview%}#use-single-or-multiple-selection). You can select a cell with mouse click anywhere in the cell. You can access the collection of selected cells, use this collection and manipulate it. You can subscribe to selection events. |
| 13 | + |
| 14 | +## Basics |
| 15 | + |
| 16 | +To select a cell, click anywhere in it. |
| 17 | + |
| 18 | +To select a range of cells in one or more columns, hold the **Shift** key, while clicking on the first and last cell of the range. To select or deselect multiple cells that don't belong to a range, hold the **Ctrl** key. |
| 19 | + |
| 20 | +You can also select a cell range by holding and dragging the mouse cursor. The dragging motion defines the diagonal of a rectangle and the Grid will select the cells under this rectangle. To allow this kind of cell selection, set the `DragToSelect` parameter in [`GridSelectionSettings`]({%slug grid-selection-overview%}#enable-row-or-cell-selection). The **Shift** and **Ctrl** modifiers are not supported in drag-to-select mode. |
| 21 | + |
| 22 | +To enable cell selection: |
| 23 | + |
| 24 | +1. Set the Grid `SelectedCells` parameter to a collection of type `IEnumerable<GridSelectedCellDescriptor>`. The collection must be initialized in advance. See [`GridSelectedCellDescriptor`](#gridselectedcelldescriptor) for infomation about the object properties. |
| 25 | +1. Add a `<GridSelectionSettings>` tag to the `<GridSettings>` tag, and set the `SelectionType` parameter to the `GridSelectionType.Cell`. |
| 26 | + |
| 27 | +>caption Grid multiple cell selection |
| 28 | +
|
| 29 | +````CSHTML |
| 30 | +<TelerikGrid Data="@GridData" |
| 31 | + SelectionMode="@GridSelectionMode.Multiple" |
| 32 | + @bind-SelectedCells="@SelectedCells" |
| 33 | + Pageable="true"> |
| 34 | + <GridSettings> |
| 35 | + <GridSelectionSettings SelectionType="@GridSelectionType.Cell" DragToSelect="true" /> |
| 36 | + </GridSettings> |
| 37 | + <GridColumns> |
| 38 | + <GridColumn Field="@nameof(Employee.Name)" /> |
| 39 | + <GridColumn Field="@nameof(Employee.Team)" /> |
| 40 | + </GridColumns> |
| 41 | +</TelerikGrid> |
| 42 | +
|
| 43 | +<h3>Selected Cells:</h3> |
| 44 | +
|
| 45 | +<ul> |
| 46 | + @foreach (GridSelectedCellDescriptor cellDescriptor in SelectedCells) |
| 47 | + { |
| 48 | + <li> |
| 49 | + Column <code>Field</code>: @cellDescriptor.ColumnField, |
| 50 | + <code>EmployeeId</code>: @( ((Employee)cellDescriptor.DataItem).EmployeeId ) |
| 51 | + </li> |
| 52 | + } |
| 53 | +</ul> |
| 54 | +
|
| 55 | +@code { |
| 56 | + private List<Employee> GridData { get; set; } = new(); |
| 57 | +
|
| 58 | + private IEnumerable<GridSelectedCellDescriptor> SelectedCells { get; set; } = Enumerable.Empty<GridSelectedCellDescriptor>(); |
| 59 | +
|
| 60 | + protected override void OnInitialized() |
| 61 | + { |
| 62 | + for (int i = 1; i <= 15; i++) |
| 63 | + { |
| 64 | + GridData.Add(new Employee() |
| 65 | + { |
| 66 | + EmployeeId = i, |
| 67 | + Name = $"Employee {i}", |
| 68 | + Team = $"Team {i % 3 + 1}" |
| 69 | + }); |
| 70 | + } |
| 71 | +
|
| 72 | + SelectedCells = new List<GridSelectedCellDescriptor>() { |
| 73 | + new GridSelectedCellDescriptor() |
| 74 | + { |
| 75 | + DataItem = GridData.ElementAt(2), |
| 76 | + ColumnField = nameof(Employee.Name) |
| 77 | + } |
| 78 | + }; |
| 79 | + } |
| 80 | +
|
| 81 | + public class Employee |
| 82 | + { |
| 83 | + public int EmployeeId { get; set; } |
| 84 | + public string Name { get; set; } = string.Empty; |
| 85 | + public string Team { get; set; } = string.Empty; |
| 86 | + } |
| 87 | +} |
| 88 | +```` |
| 89 | + |
| 90 | +## SelectedCellsChanged Event |
| 91 | + |
| 92 | +You can respond to user selection actions through the `SelectedCellsChanged` event. The event handler receives a collection of type `IEnumerable<GridSelectedCellDescriptor>`. The collection may have multiple, single, or no objects in it, depending on the `SelectionMode` and the last user selection. |
| 93 | + |
| 94 | +>caption Using the Grid SelectedCellsChanged event |
| 95 | +
|
| 96 | +````CSHTML |
| 97 | +@* Select cells and handle the SelectedCellsChanged event *@ |
| 98 | +
|
| 99 | +<TelerikGrid Data="@GridData" |
| 100 | + SelectionMode="@GridSelectionMode.Multiple" |
| 101 | + SelectedCells="@SelectedCells" |
| 102 | + SelectedCellsChanged="@( (IEnumerable<GridSelectedCellDescriptor> newSelected) => OnCellSelect(newSelected) )" |
| 103 | + Pageable="true"> |
| 104 | + <GridSettings> |
| 105 | + <GridSelectionSettings SelectionType="@GridSelectionType.Cell" DragToSelect="true" /> |
| 106 | + </GridSettings> |
| 107 | + <GridColumns> |
| 108 | + <GridColumn Field="@nameof(Employee.Name)" /> |
| 109 | + <GridColumn Field="@nameof(Employee.Team)" /> |
| 110 | + </GridColumns> |
| 111 | +</TelerikGrid> |
| 112 | +
|
| 113 | +<p><code>SelectedItemsChanged</code> fired at: @SelectedCellsChangedLog</p> |
| 114 | +
|
| 115 | +<h3>Selected Cells:</h3> |
| 116 | +
|
| 117 | +<ul> |
| 118 | + @foreach (GridSelectedCellDescriptor cellDescriptor in SelectedCells) |
| 119 | + { |
| 120 | + <li> |
| 121 | + Column <code>Field</code>: @cellDescriptor.ColumnField, |
| 122 | + <code>EmployeeId</code>: @( ((Employee)cellDescriptor.DataItem).EmployeeId ) |
| 123 | + </li> |
| 124 | + } |
| 125 | +</ul> |
| 126 | +
|
| 127 | +@code { |
| 128 | + private List<Employee> GridData { get; set; } = new(); |
| 129 | +
|
| 130 | + private IEnumerable<GridSelectedCellDescriptor> SelectedCells { get; set; } = Enumerable.Empty<GridSelectedCellDescriptor>(); |
| 131 | +
|
| 132 | + private string SelectedCellsChangedLog { get; set; } = string.Empty; |
| 133 | +
|
| 134 | + protected void OnCellSelect(IEnumerable<GridSelectedCellDescriptor> cellDescriptors) |
| 135 | + { |
| 136 | + // Update the SelectedCells collection manually. |
| 137 | + // When using two-way binding, this happens automatically. |
| 138 | + SelectedCells = cellDescriptors; |
| 139 | +
|
| 140 | + SelectedCellsChangedLog = DateTime.Now.ToLongTimeString(); |
| 141 | + } |
| 142 | +
|
| 143 | + protected override void OnInitialized() |
| 144 | + { |
| 145 | + for (int i = 1; i <= 15; i++) |
| 146 | + { |
| 147 | + GridData.Add(new Employee() |
| 148 | + { |
| 149 | + EmployeeId = i, |
| 150 | + Name = $"Employee {i}", |
| 151 | + Team = $"Team {i % 3 + 1}" |
| 152 | + }); |
| 153 | + } |
| 154 | +
|
| 155 | + SelectedCells = new List<GridSelectedCellDescriptor>() { |
| 156 | + new GridSelectedCellDescriptor() |
| 157 | + { |
| 158 | + DataItem = GridData.ElementAt(2), |
| 159 | + ColumnField = nameof(Employee.Name) |
| 160 | + } |
| 161 | + }; |
| 162 | + } |
| 163 | +
|
| 164 | + public class Employee |
| 165 | + { |
| 166 | + public int EmployeeId { get; set; } |
| 167 | + public string Name { get; set; } = string.Empty; |
| 168 | + public string Team { get; set; } = string.Empty; |
| 169 | + } |
| 170 | +} |
| 171 | +```` |
| 172 | + |
| 173 | +### SelectedCellsChanged and Asynchronous Operations |
| 174 | + |
| 175 | +The `SelectedCellsChanged` event handler cannot be awaited. To execute asynchronous operations when the user selects rows, use the [`OnRowClick`]({%slug grid-events%}#onrowclick) or [`OnRowDoubleClick`]({%slug grid-events%}#onrowdoubleclick) event instead. |
| 176 | + |
| 177 | +## GridSelectedCellDescriptor |
| 178 | + |
| 179 | +The `GridSelectedCellDescriptor` type exposes the following properties: |
| 180 | + |
| 181 | +@[template](/_contentTemplates/common/parameters-table-styles.md#table-layout) |
| 182 | + |
| 183 | +| Property Name | Type | Description | |
| 184 | +| --- | --- | --- | |
| 185 | +| `ColumnField` | `string` | The value of the [Grid column `Field`]({%slug components/grid/columns/bound%}#data-binding) parameter, if set. | |
| 186 | +| `ColumnId` | `string` | The value of the [Grid column `Id`]({%slug components/grid/columns/bound%}#identification) parameter, if set. | |
| 187 | +| `DataItem` | `object` | The Grid data item instance. Cast it to the actual Grid model type before use. | |
| 188 | + |
| 189 | +## Selection When Data Changes |
| 190 | + |
| 191 | +When the Grid `Data` collection changes, the `SelectedCells` collection has the following behavior: |
| 192 | + |
| 193 | +* When the user updates a selected cell and the item instance is replaced, you have to also replace the `SelectedCellDescriptor.DataItem` object in the `SelectedCells` collection. Do that in the [Grid `OnUpdate` event]({%slug components/grid/editing/overview%}#events). |
| 194 | +* When the user deletes a row with selected cells, update the `SelectedCells` collection in the the Grid `OnDelete` event handler. |
| 195 | +* To select cells from a new item in the Grid you can use the [`OnCreate` event]({%slug components/grid/editing/overview%}#events) to update the `SelectedCells` collection. |
| 196 | + |
| 197 | +### Equals Comparison |
| 198 | + |
| 199 | +The items in `SelectedCells` are compared against the items in the Grid data in order to determine which cells will be highlighted. The default framework behavior is to compare objects by reference. The data item references may not match when: |
| 200 | + |
| 201 | +* The Grid is databound through its `OnRead` event and each data request returns different data item instances. |
| 202 | +* The `SelectedCells` are obtained from a different data source than the all Grid items, for example, from a separate service. |
| 203 | + |
| 204 | +In such cases, the selected cells may not appear as expected. You have to [override the `Equals` method of the Grid model class]({%slug grid-state%}#equals-comparison) so that the items are compared by a unique identifier rather than by reference. When you override `Equals`, it is also recommended to override the [`GetHashCode`](https://docs.microsoft.com/en-us/dotnet/api/system.object.gethashcode) method. |
| 205 | + |
| 206 | +## Cell Selection and Other Grid Features |
| 207 | + |
| 208 | +The selection feature behavior may vary when the Grid configuration combines cell selection and other Grid features, such as editing, virtualization, paging, templates. In such cases you need to consider certain limitation or include some modications. |
| 209 | + |
| 210 | +### Selection and Editing Modes |
| 211 | + |
| 212 | +When you want to edit a Grid item, the cell selection has the following behavior: |
| 213 | + |
| 214 | +* Cell selection is not supported with [`Incell` edit mode]({%slug components/grid/editing/incell%}) due to the overlapping pointer events that trigger selection and editing. If both features are enabled, only the editing will work. |
| 215 | +* [`Inline` edit mode]({%slug components/grid/editing/inline%}) and [`Popup` edit mode]({%slug components/grid/editing/popup%}) integrate with cell selection without limitations. |
| 216 | + |
| 217 | +### Selection and Virtual Scrolling |
| 218 | + |
| 219 | +When the Grid has [virtual scrolling]({%slug components/grid/virtual-scrolling%}), the component is able to select a range of cells with **Shift** only if all rows in that range are currently rendered. Consider the following scenario: |
| 220 | + |
| 221 | +1. Select a cell. |
| 222 | +1. Scroll down, so that virtualization kicks in and the rendered rows are no longer the same. |
| 223 | +1. Select another cell with **Shift**. |
| 224 | + |
| 225 | +In this case, the range selection will start from the first row that is currently rendered. Compare with [Selection and paging](#selection-and-paging) below. |
| 226 | + |
| 227 | +### Selection and Paging |
| 228 | + |
| 229 | +The `SelectedCells` collection persists across paging. |
| 230 | + |
| 231 | +### Selection and Templates |
| 232 | + |
| 233 | +When using [Grid templates]({%slug components/grid/features/templates%}) with cell selection: |
| 234 | + |
| 235 | +* If you are using a [Grid column template]({%slug grid-templates-column%}) and you have a clickable element in the template, wrap this element in a container with a `@onclick:stopPropagation` directive. You can check the knowledge base article on [how to prevent row selection when the user clicks another component in the Grid column template]({%slug grid-kb-row-selection-in-column-template%}). It applies for both row and cell selection. |
| 236 | +* If you are using a [row template]({%slug components/grid/features/templates%}#row-template) the Grid does not support cell selection. The row template removes the built-in cell instances and the HTML markup may not even include the expected number of cells. |
| 237 | + |
| 238 | +## See Also |
| 239 | + |
| 240 | +* [Live Demo: Grid Cell Selection](https://demos.telerik.com/blazor-ui/grid/cell-selection) |
0 commit comments