Knowledge Required:
- DataGridView Control
- Windows Forms
Recently, one of our friend "Luc" asked me,
Is there an "easy" way to change the selection behavior in a datagridview so that a click on a selected row does not toggle the selection as long as the mouse button is not released, without resorting to a user-defined control with inheritence and method overrides ?
So I was about to paste the whole code in comments but that was looking a mess. So I decided to publish a new post, after a very long time :).
The solution "is" simple. We just need to look what is the event sequence. So whenever we press mouse button on a cell or row of DataGridView control, events trigger in this way,
- MouseDown
- SelectionChanged
- MouseUp
And here is the code,
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.DataGridView1.Columns.Add("Column1", "Column1")
Me.DataGridView1.Columns.Add("Column2", "Column2")
Me.DataGridView1.Columns.Add("Column3", "Column3")
Me.DataGridView1.Rows.Add("laksjdf", "alksjfsdf", "aksldjf")
Me.DataGridView1.Rows.Add("laksjdf", "alksjfsdf", "aksldjf")
Me.DataGridView1.Rows.Add("laksjdf", "alksjfsdf", "aksldjf")
Me.DataGridView1.Rows.Add("laksjdf", "alksjfsdf", "aksldjf")
Me.DataGridView1.Rows.Add("laksjdf", "alksjfsdf", "aksldjf")
Me.DataGridView1.Rows.Add("laksjdf", "alksjfsdf", "aksldjf")
Me.DataGridView1.Rows.Add("laksjdf", "alksjfsdf", "aksldjf")
' ***************************************
' IMPORTANT: MultiSelect property of DataGridView control should be False
' The result maybe same but if we set it to true then you
' may experience the flickering
' ***************************************
Me.DataGridView1.MultiSelect = False
End Sub
Private _MouseDown As Boolean
Private _PreviousSelectedCell As DataGridViewCell
Private _NewSelectedCell As DataGridViewCell
Private Sub DataGridView1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGridView1.MouseDown
' if left button is clicked
If e.Button = Windows.Forms.MouseButtons.Left Then
Me._MouseDown = True ' we will mark a flag that mouse is down
' and will note the row before the selection changed
Me._PreviousSelectedCell = Me.DataGridView1.CurrentCell
End If
End Sub
Private Sub DataGridView1_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataGridView1.SelectionChanged
If Me._MouseDown Then ' if this event is triggerd after the mouse down
' we will first note the new row on which mouse was clicked
Me._NewSelectedCell = Me.DataGridView1.CurrentCell
' then change the selection back to the one before mouse was down
Me.DataGridView1.CurrentCell = Me._PreviousSelectedCell
End If
End Sub
Private Sub DataGridView1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGridView1.MouseUp
If Me._MouseDown Then ' if this event is triggered after the mouse down
' we will set the selection to the new row which was clicked
Me.DataGridView1.CurrentCell = Me._NewSelectedCell
Me._MouseDown = False ' reset the flag
End If
End Sub
End Class