3
votes

Once I've selected multiple cells in a datagridview, I want my current cell to equal the first cell that is selected in the datagridview. The problem I'm having is, after the selection has been made (on mouse up), I set the current cell to the first selected cell (me.datagridview.currentcell =), but this removes all of the other selections in the datagridview. Does anybody know a way of changing the currentcell, without removing the datagridview selection. Current example code below:

    Private Sub DataGridView1_CellMouseUp(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseUp

    a = 0
    Do While a < Me.DataGridView1.RowCount
        b = 0
        Do While b < Me.DataGridView1.ColumnCount
            If Me.DataGridView1.Rows(a).Cells(b).Selected = True Then
                Me.DataGridView1.CurrentCell = Me.DataGridView1.Rows(a).Cells(b)
                GoTo skipstep
            End If
            b += 1
        Loop
        a += 1
    Loop

    skipstep:

    End Sub
1

1 Answers

5
votes

If you look at the source code for the CurrentCell property you'll see that it makes a call to ClearSelection before SetCurrentCellAddressCore. But you cannot call "SCCAC" because it's defined as Protected. So my best suggestion is that you subclass the DGV and create a new public method.

Public Class UIDataGridView
    Inherits DataGridView

    Public Sub SetCurrentCell(cell As DataGridViewCell)
        If (cell Is Nothing) Then
            Throw New ArgumentNullException("cell")
        'TODO: Add more validation:
        'ElseIf (Not cell.DataGridView Is Me) Then
        End If
        Me.SetCurrentCellAddressCore(cell.ColumnIndex, cell.RowIndex, True, False, False)
    End Sub

End Class

If you don't want to subclass the DGV, then reflection is your only option.

Imports System.Reflection

Private Sub HandleCellMouseDown(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseDown
    Me.firstCell = If(((e.ColumnIndex > -1) AndAlso (e.RowIndex > -1)), Me.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex), Nothing)
End Sub

Private Sub HandleCellMouseUp(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseUp
    If ((Not Me.firstCell Is Nothing) AndAlso (Me.firstCell.Selected AndAlso (Me.DataGridView1.SelectedCells.Count > 1))) Then

        Dim type As Type = GetType(DataGridView)
        Dim flags As BindingFlags = (BindingFlags.Instance Or BindingFlags.Static Or BindingFlags.Public Or BindingFlags.NonPublic)
        Dim method As MethodInfo = type.GetMethod("SetCurrentCellAddressCore", flags)

        method.Invoke(Me.DataGridView1, {Me.firstCell.ColumnIndex, Me.firstCell.RowIndex, True, False, False})

        Debug.WriteLine("First cell is current: {0}", {(Me.DataGridView1.CurrentCell Is Me.firstCell)})

    End If
End Sub

Private firstCell As DataGridViewCell

PS: Did you forget that users can select cells by using the keyboard? ;)