locked
Select All Cells in a DataGridView Column or Row on Header Click RRS feed

  • Question

  • I have a DataGridView with SelectionMode = "CellSelect".  I do this because I want the user to be able to click the Column Header and drag the column to a different DisplayIndex.  They move the column by clicking and holding down the left mouse button, then moving the column.  I also want the user to be able to click the column header and all the cells in the column would be selected.  But if I change the SelectionMode property to "FullColumnSelect" or "ColumnHeaderSelect" the user can no longer move the column.

    In the code below, I can select all the cells in the DataGridView just fine, but I can't select all cells in a particular Column or Row.  Any ideas?

        Private Sub DGV_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles dgvPending.MouseDown, dgvCurrent.MouseDown, dgvCompleted.MouseDown
    
            If e.Button = Windows.Forms.MouseButtons.Left Then
    
                Dim dgv As DataGridView = CType(sender, DataGridView)
                Dim ht As DataGridView.HitTestInfo = dgv.HitTest(e.X, e.Y)
    
                dgv.SuspendLayout()
    
                Select Case ht.Type
    
                    ' select all cells
                    Case Is = DataGridViewHitTestType.TopLeftHeader
                        dgv.SelectAll()
    
                        'select the entire column
                    Case Is = DataGridViewHitTestType.ColumnHeader
                        dgv.Columns(ht.ColumnIndex).Selected = True
                        For i As Integer = 0 To dgv.Rows.Count - 1
                            dgv.Item(i, ht.ColumnIndex).Selected = True
                        Next
    
                        'select all cells in the row entire row
                    Case Is = DataGridViewHitTestType.RowHeader
                        dgv.Rows(ht.RowIndex).Selected = True
                        For i As Integer = 0 To dgv.Columns.Count - 1
                            dgv.Item(ht.RowIndex, i).Selected = True
                        Next
                End Select
                dgv.ResumeLayout()
            End If
    
            ' call the appropriate context menu
            If e.Button = Windows.Forms.MouseButtons.Right Then
    
                Dim dgv As DataGridView = CType(sender, DataGridView)
    
                Select Case dgv.Name
                    Case Is = "dgvPending" : Me.penDGVSettings.ShowContextMenu(sender, e, Me.flpPending)
                    Case Is = "dgvCurrent" : Me.curDGVSettings.ShowContextMenu(sender, e, Me.flpCurrent)
                    Case Is = "dgvCompleted" : Me.comDGVSettings.ShowContextMenu(sender, e, Me.flpCompleted)
                End Select
            End If
    
        End Sub

    Thanks in advance,


    Ryan

    Monday, April 2, 2012 9:38 PM

Answers

  • Better to use MouseUp instead of MouseDown, otherwise, the column sort may unselect the cells.

    And change your code as:

      If e.Button = Windows.Forms.MouseButtons.Left Then
    
        Dim dgv As DataGridView = CType(sender, DataGridView)
        Dim ht As DataGridView.HitTestInfo = dgv.HitTest(e.X, e.Y)
    
        dgv.SuspendLayout()
    
        Select Case ht.Type
    
          ' select all cells
          Case Is = DataGridViewHitTestType.TopLeftHeader
            dgv.ClearSelection()
            dgv.SelectAll()
    
            'select the entire column
          Case Is = DataGridViewHitTestType.ColumnHeader
            dgv.ClearSelection()
            dgv.Columns(ht.ColumnIndex).Selected = True
            For i As Integer = 0 To dgv.Rows.Count - 1
              dgv.Rows(i).Cells(ht.ColumnIndex).Selected = True
            Next
    
            'select all cells in the row entire row
          Case Is = DataGridViewHitTestType.RowHeader
            dgv.ClearSelection()
            dgv.Rows(ht.RowIndex).Selected = True
            For i As Integer = 0 To dgv.Columns.Count - 1
              dgv.Rows(ht.RowIndex).Cells(i).Selected = True
            Next
        End Select
        dgv.ResumeLayout()
      End If



    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us


    • Edited by Jie Bao Tuesday, April 3, 2012 5:43 AM
    • Marked as answer by Ryan0827 Thursday, April 5, 2012 9:30 AM
    Tuesday, April 3, 2012 5:41 AM
  • Cor, I realize the DataGridView is made up of a collection of rows and not a collection of columns.  However, the end user does not know that the DataGridView functions differently from a spreadsheet so I try my best to accommodate for that.

    Thanks Bob for the showing me the ClearSelection() method.  I did not know about this and I can use this in other places in my application.

    I figured out a work around last night.  Since the DataGridView has its SelectionMode = "CellSelect" at design time, I decided to keep my MouseDown event and ask the user to hold the Ctrl key while selecting Columns or Rows.  If the Ctrl key is held down I change the SelectionMode to "FullColumnSelect" or "ColumnHeaderSelect".  What do you think?

        Private Sub DGV_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles dgvPending.MouseDown, dgvCurrent.MouseDown, dgvCompleted.MouseDown
    
            If e.Button = Windows.Forms.MouseButtons.Left Then
    
                Dim dgv As DataGridView = CType(sender, DataGridView)
    
                Select Case dgv.HitTest(e.X, e.Y).Type
    
                    ' select all cells
                    Case Is = DataGridViewHitTestType.TopLeftHeader
                        dgv.ClearSelection()
                        dgv.SelectAll()
    
                        'select the entire column
                    Case Is = DataGridViewHitTestType.ColumnHeader
    
                        ' user must click column header + Ctrl key to select all cells in a column, if not the column can be moved to change display index 
                        If Control.ModifierKeys = Keys.Control Then
                            ' allows user to select all cells in the column
                            dgv.SelectionMode = DataGridViewSelectionMode.ColumnHeaderSelect
                            ' un-select the current cell if it is not part of the selected columns
                            If Not dgv.SelectedColumns.Contains(dgv.Columns(dgv.CurrentCell.ColumnIndex)) Then
                                dgv.CurrentCell.Selected = False
                            End If
                        Else
                            ' this is the dgv default setting so users can left click column header and move column to change display index
                            dgv.SelectionMode = DataGridViewSelectionMode.CellSelect
                        End If
    
                        'select all cells in the row entire row
                    Case Is = DataGridViewHitTestType.RowHeader
    
                        ' user must click row header + Ctrl key to select all cells in the row
                        If Control.ModifierKeys = Keys.Control Then
                            ' allows user to select all cells in the row
                            dgv.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect
                            ' un-select the current cell if it is not part of the selected rows
                            If Not dgv.SelectedRows.Contains(dgv.Rows(dgv.CurrentCell.RowIndex)) Then
                                dgv.CurrentCell.Selected = False
                            End If
                        Else
                            ' this is the dgv default setting so users can left click column header and move column to change display index
                            dgv.SelectionMode = DataGridViewSelectionMode.CellSelect
                        End If
                End Select
            End If
    
        End Sub

    Ryan

    • Marked as answer by Ryan0827 Thursday, April 5, 2012 9:30 AM
    Tuesday, April 3, 2012 1:15 PM

All replies

  • You can select a row, but you cannot select a column.

    An often made mistake is that some think that an whatever DataGrid is a spreadsheet; it is not

    A DataGrid exist from rows of items which get there (same) description because they are in the same column.

    However a column itself is not a collection of items like in a spreadsheet.

     


    Success
    Cor

    • Proposed as answer by Jie Bao Tuesday, April 3, 2012 5:20 AM
    Tuesday, April 3, 2012 5:18 AM
  • Better to use MouseUp instead of MouseDown, otherwise, the column sort may unselect the cells.

    And change your code as:

      If e.Button = Windows.Forms.MouseButtons.Left Then
    
        Dim dgv As DataGridView = CType(sender, DataGridView)
        Dim ht As DataGridView.HitTestInfo = dgv.HitTest(e.X, e.Y)
    
        dgv.SuspendLayout()
    
        Select Case ht.Type
    
          ' select all cells
          Case Is = DataGridViewHitTestType.TopLeftHeader
            dgv.ClearSelection()
            dgv.SelectAll()
    
            'select the entire column
          Case Is = DataGridViewHitTestType.ColumnHeader
            dgv.ClearSelection()
            dgv.Columns(ht.ColumnIndex).Selected = True
            For i As Integer = 0 To dgv.Rows.Count - 1
              dgv.Rows(i).Cells(ht.ColumnIndex).Selected = True
            Next
    
            'select all cells in the row entire row
          Case Is = DataGridViewHitTestType.RowHeader
            dgv.ClearSelection()
            dgv.Rows(ht.RowIndex).Selected = True
            For i As Integer = 0 To dgv.Columns.Count - 1
              dgv.Rows(ht.RowIndex).Cells(i).Selected = True
            Next
        End Select
        dgv.ResumeLayout()
      End If



    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us


    • Edited by Jie Bao Tuesday, April 3, 2012 5:43 AM
    • Marked as answer by Ryan0827 Thursday, April 5, 2012 9:30 AM
    Tuesday, April 3, 2012 5:41 AM
  • Hi,

    Can't you use 3rd party tool?

    Tuesday, April 3, 2012 7:36 AM
  • Cor, I realize the DataGridView is made up of a collection of rows and not a collection of columns.  However, the end user does not know that the DataGridView functions differently from a spreadsheet so I try my best to accommodate for that.

    Thanks Bob for the showing me the ClearSelection() method.  I did not know about this and I can use this in other places in my application.

    I figured out a work around last night.  Since the DataGridView has its SelectionMode = "CellSelect" at design time, I decided to keep my MouseDown event and ask the user to hold the Ctrl key while selecting Columns or Rows.  If the Ctrl key is held down I change the SelectionMode to "FullColumnSelect" or "ColumnHeaderSelect".  What do you think?

        Private Sub DGV_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles dgvPending.MouseDown, dgvCurrent.MouseDown, dgvCompleted.MouseDown
    
            If e.Button = Windows.Forms.MouseButtons.Left Then
    
                Dim dgv As DataGridView = CType(sender, DataGridView)
    
                Select Case dgv.HitTest(e.X, e.Y).Type
    
                    ' select all cells
                    Case Is = DataGridViewHitTestType.TopLeftHeader
                        dgv.ClearSelection()
                        dgv.SelectAll()
    
                        'select the entire column
                    Case Is = DataGridViewHitTestType.ColumnHeader
    
                        ' user must click column header + Ctrl key to select all cells in a column, if not the column can be moved to change display index 
                        If Control.ModifierKeys = Keys.Control Then
                            ' allows user to select all cells in the column
                            dgv.SelectionMode = DataGridViewSelectionMode.ColumnHeaderSelect
                            ' un-select the current cell if it is not part of the selected columns
                            If Not dgv.SelectedColumns.Contains(dgv.Columns(dgv.CurrentCell.ColumnIndex)) Then
                                dgv.CurrentCell.Selected = False
                            End If
                        Else
                            ' this is the dgv default setting so users can left click column header and move column to change display index
                            dgv.SelectionMode = DataGridViewSelectionMode.CellSelect
                        End If
    
                        'select all cells in the row entire row
                    Case Is = DataGridViewHitTestType.RowHeader
    
                        ' user must click row header + Ctrl key to select all cells in the row
                        If Control.ModifierKeys = Keys.Control Then
                            ' allows user to select all cells in the row
                            dgv.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect
                            ' un-select the current cell if it is not part of the selected rows
                            If Not dgv.SelectedRows.Contains(dgv.Rows(dgv.CurrentCell.RowIndex)) Then
                                dgv.CurrentCell.Selected = False
                            End If
                        Else
                            ' this is the dgv default setting so users can left click column header and move column to change display index
                            dgv.SelectionMode = DataGridViewSelectionMode.CellSelect
                        End If
                End Select
            End If
    
        End Sub

    Ryan

    • Marked as answer by Ryan0827 Thursday, April 5, 2012 9:30 AM
    Tuesday, April 3, 2012 1:15 PM
  • Hi Ryan,

    Of couse, it can. You just define the rules.

    However, for a the user experience, you should listen the customers' feedback for this rule, press CLT and we can select the Row and Column.

    For the feature and the code, that is fine.


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us

    Wednesday, April 4, 2012 3:38 AM