Home > Blockchain >  How do I select a range in .Net DataGridView?
How do I select a range in .Net DataGridView?

Time:09-15

I want to select a range (or rectangle) of cells in a .Net DataGridView. I could not find a built in method to do this. I came up with the code below, but there has to be a better way.

    Public Sub setDataGridViewSelectedRange(ByRef gridCntl As DataGridView, rowStart As Int32, colStart As Int32, rowEnd As Int32, colEnd As Int32)
        Dim curRow As Int32
        Dim curCol As Int32
        For curRow = rowStart To rowEnd
            For curCol = colStart To colEnd
                gridCntl(curRow, curCol).Selected = True
            Next
        Next
    End Sub

CodePudding user response:

Are you using System.Windows.Forms? In WPF the DataGrid control has two properties SelectionMode and SelectionUnit.

The SelectionMode can be set to Single or Extended to define if one or multiple units can be selected simultaneously. The SelectionUnit defines the scope of one selection unit. It can be set to Cell, CellAndRowHeader and FullRow. https://www.wpftutorial.net/datagrid.html

CodePudding user response:

I came up with the code below, but there has to be a better way.

I don't think there is a better way, all what you can find around are just variations of your code snippet, either by using simple nested loops as you do, or by looping the results returned by LINQ quires.

However, you can optimize the code taking into account the DataGridView.SelectionMode property. You don't need nested or complete loops when it is set to FullColumnSelect or FullRowSelect values. Moreover, for the other selection mode values, you can optionally make a connected selection, that is, selecting all the cells between the given staring and ending cells of the given rows.

Here's an extension method example, add a new module if you don't have one or to separate the project's extension methods. Switch to the Solution Explorer window, select the project, right mouse click, go to Add - Module, name it Extensions for example and hit Add.

Imports System.Runtime.CompilerServices

Module Extensions

    <Extension>
    Public Sub SelectRange(
                    gridCntl As DataGridView,
                    rowStart As Integer,
                    colStart As Integer,
                    rowEnd As Integer,
                    colEnd As Integer,
                    connected As Boolean)
        gridCntl.ClearSelection()

        Select Case gridCntl.SelectionMode
            Case DataGridViewSelectionMode.FullRowSelect
                ' Just Select the rows...
                For row = rowStart To rowEnd
                    gridCntl.Rows(row).Selected = True
                Next
            Case DataGridViewSelectionMode.FullColumnSelect
                ' Just select the columns of the first row...
                For row = rowStart To rowStart
                    For col = colStart To colEnd
                        gridCntl(col, row).Selected = True
                    Next
                Next
            Case Else
                ' For the rest, select either normal or connected selection...
                Dim colFrom As Integer = colStart, colTo As Integer
                For row = rowStart To rowEnd
                    Dim notLastRow As Boolean = row < rowEnd
                    colTo = If(connected AndAlso notLastRow,
                        gridCntl.Columns.Count - 1,
                        colEnd)
                    For col = colFrom To colTo
                        gridCntl(col, row).Selected = True
                    Next
                    colFrom = If(connected AndAlso notLastRow, 0, colStart)
                Next
        End Select
    End Sub

End Module

Call the extension method...

Sub SomeCaller()
    SomeDGV.SelectRange(1, 2, 5, 1, True) ' or False...
End Sub

Side Notes

  • No point from passing a reference type or a control ByRef.
  • The DataGridView indexer receives the column and row indices respectively.
  • Related