Back to Devexpress

Multiple Row and Cell Selection

windowsforms-711-controls-and-libraries-data-grid-focus-and-selection-handling-multiple-row-and-cell-selection.md

latest33.9 KB
Original Source

Multiple Row and Cell Selection

  • Jul 02, 2024
  • 13 minutes to read

The DevExpress Grid control supports the following selection options:

  • Multiple Row/Card Selection – A user can select several rows/cards.
  • Multiple Cell Selection – A user can select multiple cells within different rows.
  • Single Row/Card Selection – A user can select only one row or card at the same time. The ‘selected’ row/card is called the focused row/card.

Multiple Row/Card Selection Mode

In multiple row/card selection mode, a user can select multiple rows/cards:

Multiple row/card selection is supported by the following Views:

Enable Multiple Row Selection

To enable multiple row/card selection, set the View’s OptionsSelection.MultiSelect property to true :

csharp
gridView1.OptionsSelection.MultiSelect = true;
vb
gridView1.OptionsSelection.MultiSelect = True

Select Rows in Code

csharp
//Enable multiple row selection.
gridView1.OptionsSelection.MultiSelect = true;
//Select the second, third, and fourth rows.
gridView1.SelectRows(1, 3);
vb
'Enable multiple row selection.
gridView1.OptionsSelection.MultiSelect = True
'Select the second, third, and fourth rows.
gridView1.SelectRows(1, 3)

Web Style Row Selection in GridView

The GridView supports Web style row selection. In this mode, the GridView displays a column with check boxes:

Watch Video: Web Style Row Selection

Set the GridView’s OptionsSelection.MultiSelectMode property to GridMultiSelectMode.CheckBoxRowSelect to enable Web style row selection:

csharp
using DevExpress.XtraGrid.Views.Grid;

//...
gridView1.OptionsSelection.MultiSelect = true;
gridView1.OptionsSelection.MultiSelectMode = GridMultiSelectMode.CheckBoxRowSelect;
vb
Imports DevExpress.XtraGrid.Views.Grid

'...
gridView1.OptionsSelection.MultiSelect = True
gridView1.OptionsSelection.MultiSelectMode = GridMultiSelectMode.CheckBoxRowSelect

Tip

You can bind selected state of rows to a data source field.

Read the following topic for additional information and examples: Web Style Row Selection and Selection Binding.

|

API Member

|

Description

| | --- | --- | |

SelectRow(Int32)

|

Selects the specified row/card.

| |

SelectRows(Int32, Int32)

SelectRange(Int32, Int32)

|

Selects specified rows/cards.

| |

UnselectRow(Int32)

|

Deselects the specified row/card.

| |

ClearSelection()

|

Clears the selection.

| |

SelectedRowsCount

|

Gets the number of selected rows.

| |

GetSelectedRows()

|

Returns an integer array that contains handles of selected rows.

| |

SelectionChanged

|

Occurs after selection has been changed.

| |

BeginSelection()

EndSelection()

|

These methods prevent excessive updates when doing several selection-related operations in code.

|

Run Demo: Obtain Selected Rows

Performance Improvements

Each time you select or deselect a row, the View raises the SelectionChanged event. Sequential calling of selection-related APIs may slow down application performance. Enclose sequential selection-related modifications within BeginSelection() and EndSelection() method calls:

csharp
using System.ComponentModel;
using DevExpress.Data;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Views.Grid;

namespace DXApplication {
    public partial class Form1 : XtraForm {
        public Form1() {
            InitializeComponent();
            BindGridControl();
            //Enable multiple row selection.
            gridView1.OptionsSelection.MultiSelect = true;

            gridView1.SelectionChanged += GridView1_SelectionChanged;
            simpleButton1.Click += SimpleButton1_Click;
        }
        void SimpleButton1_Click(object sender, System.EventArgs e) {
            //Select rows based on a condition.
            SelectRoles("Guest", gridView1);
        }
        void GridView1_SelectionChanged(object sender, SelectionChangedEventArgs e) {
            memoEdit1.AppendText("The GridView's SelectionChanged event raised.\r\n");
        }
        void SelectRoles(string role, GridView gridView) {
            int rowHandle;
            gridView.BeginSelection();
            for(int i = 0; i < gridView1.RowCount; i++) {
                rowHandle = gridView.GetVisibleRowHandle(i);
                if (gridView.GetRowCellValue(gridView.GetVisibleRowHandle(i), "Role").ToString() == role)
                    gridView.SelectRow(rowHandle);
            }
            gridView.EndSelection();
        }
        void BindGridControl(){
            gridControl1.DataSource = new BindingList<DataItem>() {
                new DataItem(){ Role = "Admin", FullName = "Mike Spirit" },
                new DataItem(){ Role = "Guest", FullName = "Nathan White" },
                new DataItem(){ Role = "Guest", FullName = "Amanda Lee" },
                new DataItem(){ Role = "Moderator", FullName = "Jason Norton" },
                new DataItem(){ Role = "Moderator", FullName = "Mike Morris" },
            };
        }
    }

    public class DataItem {
        public string Role { get; set; }
        public string FullName { get; set; }
    }
}
vb
Imports Microsoft.VisualBasic
Imports System.ComponentModel
Imports DevExpress.Data
Imports DevExpress.XtraEditors
Imports DevExpress.XtraGrid.Views.Grid

Namespace DXApplication
    Partial Public Class Form1
        Inherits XtraForm

        Public Sub New()
            InitializeComponent()
            BindGridControl()
            'Enable multiple row selection.
            gridView1.OptionsSelection.MultiSelect = True

            AddHandler gridView1.SelectionChanged, AddressOf GridView1_SelectionChanged
            AddHandler simpleButton1.Click, AddressOf SimpleButton1_Click
        End Sub
        Private Sub SimpleButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs)
            'Select rows based on a condition.
            SelectRoles("Guest", gridView1)
        End Sub
        Private Sub GridView1_SelectionChanged(ByVal sender As Object, ByVal e As SelectionChangedEventArgs)
            memoEdit1.AppendText("The GridView's SelectionChanged event raised." & vbCrLf)
        End Sub
        Private Sub SelectRoles(ByVal role As String, ByVal gridView As GridView)
            Dim rowHandle As Integer
            gridView.BeginSelection()
            For i As Integer = 0 To gridView1.RowCount - 1
                rowHandle = gridView.GetVisibleRowHandle(i)
                If gridView.GetRowCellValue(gridView.GetVisibleRowHandle(i), "Role").ToString() = role Then
                    gridView.SelectRow(rowHandle)
                End If
            Next i
            gridView.EndSelection()
        End Sub
        Private Sub BindGridControl()
            gridControl1.DataSource = New BindingList(Of DataItem)() From {
                New DataItem() With {
                    .Role = "Admin",
                    .FullName = "Mike Spirit"
                },
                New DataItem() With {
                    .Role = "Guest",
                    .FullName = "Nathan White"
                },
                New DataItem() With {
                    .Role = "Guest",
                    .FullName = "Amanda Lee"
                },
                New DataItem() With {
                    .Role = "Moderator",
                    .FullName = "Jason Norton"
                },
                New DataItem() With {
                    .Role = "Moderator",
                    .FullName = "Mike Morris"
                }
            }
        End Sub
    End Class

    Public Class DataItem
        Public Property Role() As String
        Public Property FullName() As String
    End Class
End Namespace

Read the following topic for additional information: Batch Modifications.

Multiple Cell Selection Mode

In multiple cell selection mode, users can select multiple cells within different rows:

Run Demo: Cell Selection

Multiple cell selection is supported by the following views:

Enable Multiple Cell Selection

To enable multiple cell selection mode, set the View’s OptionsSelection.MultiSelect property to true and the OptionsSelection.MultiSelectMode property to GridMultiSelectMode.CellSelect:

csharp
using DevExpress.XtraGrid.Views.Grid;

//...
gridView1.OptionsSelection.MultiSelect = true;
gridView1.OptionsSelection.MultiSelectMode = GridMultiSelectMode.CellSelect;
vb
Imports DevExpress.XtraGrid.Views.Grid

'...
gridView1.OptionsSelection.MultiSelect = True
gridView1.OptionsSelection.MultiSelectMode = GridMultiSelectMode.CellSelect

Select Multiple Cells in Code

csharp
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;

//...
gridView1.OptionsSelection.MultiSelect = true;
gridView1.OptionsSelection.MultiSelectMode = GridMultiSelectMode.CellSelect;
gridView1.SelectCell(0, gridView1.Columns["Role"]);
gridView1.SelectCells(new GridCell(1, gridView1.Columns["FullName"]), new GridCell(3, gridView1.Columns["FullName"]));
vb
Imports DevExpress.XtraGrid.Views.Base
Imports DevExpress.XtraGrid.Views.Grid

'...
gridView1.OptionsSelection.MultiSelect = True
gridView1.OptionsSelection.MultiSelectMode = GridMultiSelectMode.CellSelect
gridView1.SelectCell(0, gridView1.Columns("Role"))
gridView1.SelectCells(New GridCell(1, gridView1.Columns("FullName")), New GridCell(3, gridView1.Columns("FullName")))

The image below shows the result:

The following table lists related APIs:

API MemberDescription
SelectCellSelects the specified cell.
SelectCellsSelects a range of cells.
SelectAll()Selects all cells within the View.
UnselectCellDeselects the specified cell.
UnSelectCellsDeselects a range of cells.
ClearSelection()Clears selection.
GetSelectedCellsReturns selected cells.
GetSelectedRows()Returns handles of rows that contain selected cells.

Single Row/Card Selection (Focused Row)

Multiple row/cell selection is disabled by default. A user can select (focus) only one row/card at the same time.

Difference Between Focused and Selected Rows

The focused row (or a card in the CardView) is the row that accepts input from a user. There can only be one focused row in a View, regardless of the selection mode. Multiple row selection is a visual feature that highlights specific rows.

Note

When multiple row selection is enabled and the user focuses a new row, the row is selected (highlighted). When you focus a row in code, the row is not automatically selected (highlighted).

The following images demonstrate selected and deselected states of the focused row:

|

Focused Row is selected

|

The ColumnView.GetSelectedRows method returns three row handles, including the focused row handle.

| |

Focused Row is deselected

|

The ColumnView.GetSelectedRows method returns two handles that correspond to selected rows. The focused row handle will not be included in the method’s resulting array.

|

The table below lists related APIs:

|

API Member

|

Description

| | --- | --- | |

FocusedRowHandle

|

Gets or sets the focused (selected) row/card.

| |

FocusedRowChanged

|

This event occurs after the focused row has been changed.

| |

GetSelectedRows

|

In single row/card selection mode, the GetSelectedRows method returns an integer array that contains a single element (the focused row’s handle).

| |

SelectedRowsCount

|

In single row/card selection mode, the SelectedRowsCount property returns 1.

|

Read the following topics for additional information:

APIs to Work with Selection and Rows

|

API Member

|

Description

| | --- | --- | |

BaseView.CopyToClipboard

|

Copies the focused or selected record(s) to the Clipboard as text.

| |

ColumnView.DeleteRow

|

Deletes a specific row/card.

| |

ColumnView.DeleteSelectedRows

|

Deletes the focused or selected rows.

| |

ColumnView.GetRow

|

Returns an object that contains a specified row.

| |

ColumnView.GetDataRow

|

Returns a DataRow object that contains a specified row.

| |

ColumnView.GetRowCellValue

ColumnView.GetFocusedRowCellValue

|

Gets the value in a row’s field.

| |

ColumnView.GetRowCellDisplayText

ColumnView.GetFocusedRowCellDisplayText

|

Gets the text representation of a row’s value.

| |

ColumnView.SetRowCellValue

ColumnView.SetFocusedRowCellValue

|

Assigns a value to a row’s cell.

|

End-User Capabilities

A user can select rows/cards and cells with a mouse and keyboard. Please refer to the following topic for more information: End-User Capabilities: Selecting Rows/Cards.

Prevent Users from Selecting Specific Rows/Cells Based on a Condition

Handle the SelectionChanging event to control whether a user can select or deselect specific rows/cards/cells based on a condition.

The following code sample does not allow users to select the first 5 rows:

csharp
gridView1.SelectionChanging += (s, e) => {
    e.Cancel = e.Action == CollectionChangeAction.Add && e.ControllerRow <= 4;
};
vb
gridView1.SelectionChanging += Function(s, e)
    e.Cancel = e.Action = CollectionChangeAction.Add AndAlso e.ControllerRow <= 4
End Function

Customize Appearance of Selected and Focused Rows/Cells

Selected and focused rows are painted with the same appearance settings. Use appearance-related properties of the View’s Appearance object (GridView.Appearance, CardView.Appearance, etc.).

API MemberDescription
GridViewAppearances.FocusedRowContains appearance settings used to paint the focused row.
GridViewAppearances.SelectedRowContains appearance settings used to paint selected rows.
GridViewAppearances.HideSelectionRowContains appearance settings used to paint selected rows when the Grid Control is not focused.
CardViewAppearances.FocusedCardCaptionContains appearance settings used to paint the caption of the focused card.
CardViewAppearances.SelectedCardCaptionContains appearance settings used to paint captions of selected cards.
CardViewAppearances.HideSelectionCardCaptionContains appearance settings used to paint captions of selected cards when the Grid Control is not focused.

Appearance Priority

Row appearance settings take priority over column appearance settings (GridColumn.AppearanceCell). To prioritize column appearance settings, enable the GridColumn.AppearanceCell.Options.HighPriority option:

csharp
gridColumn1.AppearanceCell.Options.HighPriority = true;
vb
GridColumn1.AppearanceCell.Options.HighPriority = True

Read the following topic for additional information: Priority of Appearance Objects.

Customize Appearance of Specific Selected Rows/Cells

Handle the following events to customize appearance settings of cells within selected rows:

Disable Focused Row/Cell Appearance

To prevent the focused row from being highlighted, set the View’s OptionsSelection.EnableAppearanceFocusedRow property to false. The View’s OptionsSelection.EnableAppearanceFocusedCell property allows you to disable coloring of a focused cell.

The following example disables focused cell appearance settings and keeps the focused row’s appearance when the Grid Control loses focus:

csharp
void Form1_Load(object sender, EventArgs e) {
    gridView1.OptionsSelection.EnableAppearanceHideSelection = false;
    gridView1.OptionsSelection.EnableAppearanceFocusedCell = false;
}
vb
Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
    gridView1.OptionsSelection.EnableAppearanceHideSelection = False
    gridView1.OptionsSelection.EnableAppearanceFocusedCell = False
End Sub

Tip

To prevent selected/focused rows from being highlighted when the grid control is not focused, use the View’s OptionsSelection.EnableAppearanceHideSelection property.

Disable Selected Row/Cell Appearance

You can use the following techniques to display selected rows and cells without highlight effects:

Example - Obtain Selected Rows

This example obtains selected rows and modifies their values in the “Discounted” column.

If data is sorted or filtered, changes made to one grid row can make other rows change their order and, as a result, their row handles. For this reason, you cannot access selected rows by their handles and process these rows right away. Instead, pass row handles retrieved by the ColumnView.GetSelectedRows method to the ColumnView.GetDataRow method. This allows you to access underlying data source objects (in this example, DataRows), save them to an array, and safely change their values afterwards.

Each row modification forces the Grid View to update itself. The example encloses the code within BaseView.BeginUpdate and BaseView.EndUpdate method calls to avoid excessive updates.

csharp
ArrayList rows = new ArrayList();

// Add the selected rows to the list.
Int32[] selectedRowHandles = gridView1.GetSelectedRows();
for (int i = 0; i < selectedRowHandles.Length; i++) {
    int selectedRowHandle = selectedRowHandles[i];
    if (selectedRowHandle >= 0)
        rows.Add(gridView1.GetDataRow(selectedRowHandle));
}
try {
    gridView1.BeginUpdate();
    for (int i = 0; i < rows.Count; i++) {
        DataRow row = rows[i] as DataRow;
        // Change the field value.
        row["Discontinued"] = true;
    }
}
finally {
    gridView1.EndUpdate();
}
vb
Dim Rows As New ArrayList()

' Add the selected rows to the list.
Dim selectedRowHandles As Int32() = GridView1.GetSelectedRows()
Dim I As Integer
For I = 0 To selectedRowHandles.Length - 1
    Dim selectedRowHandle As Int32 = selectedRowHandles(I)
    If (selectedRowHandle >= 0) Then
        Rows.Add(GridView1.GetDataRow(selectedRowHandle))
    End If
Next
Try
    GridView1.BeginUpdate()
    For I = 0 To Rows.Count - 1
        Dim Row As DataRow = CType(Rows(I), DataRow)
        ' Change the field value.
        Row("Discontinued") = True
    Next
Finally
    GridView1.EndUpdate()
End Try

Run Demo: Obtain Selected Rows

Example - Select a Column

The following example emulates the behavior introduced in Microsoft Excel (when a user left-clicks a column header, all cells displayed within this column are highlighted):

csharp
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;
using DevExpress.Data;
using DevExpress.XtraGrid.Columns;
using DevExpress.Utils;

namespace DXApplication16 {
    public partial class Form1 : FluentDesignForm {
        // The list of selected columns:
        ArrayList selectedColumns;

        public Form1() {
            InitializeComponent();
            gridView1.MouseDown += GridView1_MouseDown;
            this.Load += Form1_Load;
        }

        private void Form1_Load(object sender, System.EventArgs e) {
            selectedColumns = new ArrayList();
        }

        private void GridView1_MouseDown(object sender, MouseEventArgs e) {
            GridView view = sender as GridView;
            GridHitInfo info = view.CalcHitInfo(new Point(e.X, e.Y));

            if (info.InColumn & e.Button == MouseButtons.Left) {
                // Disable sort operations when a user left-clicks a header.
                info.Column.OptionsColumn.AllowSort = DefaultBoolean.False;
                // Check whether the clicked column is already in the list.
                if (!selectedColumns.Contains(info.Column.FieldName)) {
                    // If not, custom draw its cells and add it to the list.
                    info.Column.AppearanceCell.Assign(view.PaintAppearance.SelectedRow);
                    selectedColumns.Add(info.Column.Name);
                }
                else {
                    // Otherwise, remove this column from the selected columns list
                    // and reset its cell appearances.
                    selectedColumns.Remove(info.Column.Name);
                    info.Column.AppearanceCell.Reset();
                }
            }
            else {
                // If anything but a column header is clicked,
                // reset all column cell appearances and clear the list.
                if (selectedColumns.Count != 0) {
                    foreach (string name in selectedColumns)
                        view.Columns.ColumnByName(name).AppearanceCell.BackColor =
                            Color.Transparent;
                    selectedColumns.Clear();
                }
            }

            // Users can still right-click a header and choose sort options.
            if (info.InColumn & e.Button == MouseButtons.Right) {
                info.Column.OptionsColumn.AllowSort = DefaultBoolean.Default;
            }
        }
    }
}
vb
Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraGrid.Views.Grid.ViewInfo
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Drawing
Imports DevExpress.Data
Imports DevExpress.XtraGrid.Columns
Imports DevExpress.Utils

Namespace DXApplication16
    Partial Public Class Form1
        Inherits FluentDesignForm

        ' The list of selected columns:
        Private selectedColumns As ArrayList

        Public Sub New()
            InitializeComponent()
            AddHandler gridView1.MouseDown, AddressOf GridView1_MouseDown
            AddHandler Me.Load, AddressOf Form1_Load
        End Sub

        Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs)
            selectedColumns = New ArrayList()
        End Sub

        Private Sub GridView1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
            Dim view As GridView = TryCast(sender, GridView)
            Dim info As GridHitInfo = view.CalcHitInfo(New Point(e.X, e.Y))

            If info.InColumn And e.Button = MouseButtons.Left Then
                ' Disable sort operations when a user left-clicks a header.
                info.Column.OptionsColumn.AllowSort = DefaultBoolean.False
                ' Check whether the clicked column is already in the list.
                If Not selectedColumns.Contains(info.Column.FieldName) Then
                    ' If not, custom draw its cells and add it to the list.
                    info.Column.AppearanceCell.Assign(view.PaintAppearance.SelectedRow)
                    selectedColumns.Add(info.Column.Name)
                Else
                    ' Otherwise, remove this column from the selected columns list
                    ' and reset its cell appearances.
                    selectedColumns.Remove(info.Column.Name)
                    info.Column.AppearanceCell.Reset()
                End If
            Else
                ' If anything but a column header is clicked,
                ' reset all column cell appearances and clear the list.
                If selectedColumns.Count <> 0 Then
                    For Each name As String In selectedColumns
                        view.Columns.ColumnByName(name).AppearanceCell.BackColor = Color.Transparent
                    Next name
                    selectedColumns.Clear()
                End If
            End If

            ' Users can still right-click a header and choose sort options.
            If info.InColumn And e.Button = MouseButtons.Right Then
                info.Column.OptionsColumn.AllowSort = DefaultBoolean.Default
            End If
        End Sub
    End Class
End Namespace

Run Demo: How to Select a Column in Excel Style

Notes

Data Grid cells can embed interactive editors (for instance, check boxes or ButtonEdit buttons). When multiple row/cell selection is enabled, clicking such UI elements activates the cell but its editor does not raise events (for example, Click or CheckedChanged) because the editor does not yet exist. To trigger these events, a user must click the element the second time.

To change this behavior, set the ColumnViewOptionsBehavior.EditorShowMode property to EditorShowMode.MouseDown.

See Also

Rows

Batch Modifications

Examples: Navigation and Selection

End-User Capabilities: Selecting Rows/Cards

Multiple Row Selection using Built-In Check Column and Selection Binding