I'd like to deselect all selected rows in a DataGridView
control when the user clicks on a blank (non-row) part of the control.
How can I do this?
6 Answers
To deselect all rows and cells in a DataGridView
, you can use the ClearSelection
method:
myDataGridView.ClearSelection()
If you don't want even the first row/cell to appear selected, you can set the CurrentCell
property to Nothing
/null
, which will temporarily hide the focus rectangle until the control receives focus again:
myDataGridView.CurrentCell = Nothing
To determine when the user has clicked on a blank part of the DataGridView
, you're going to have to handle its MouseUp
event. In that event, you can HitTest
the click location and watch for this to indicate HitTestInfo.Nowhere
. For example:
Private Sub myDataGridView_MouseUp(ByVal sender as Object, ByVal e as System.Windows.Forms.MouseEventArgs)
''# See if the left mouse button was clicked
If e.Button = MouseButtons.Left Then
''# Check the HitTest information for this click location
If myDataGridView.HitTest(e.X, e.Y) = DataGridView.HitTestInfo.Nowhere Then
myDataGridView.ClearSelection()
myDataGridView.CurrentCell = Nothing
End If
End If
End Sub
Of course, you could also subclass the existing DataGridView
control to combine all of this functionality into a single custom control. You'll need to override its OnMouseUp
method similar to the way shown above. I also like to provide a public DeselectAll
method for convenience that both calls the ClearSelection
method and sets the CurrentCell
property to Nothing
.
(Code samples are all arbitrarily in VB.NET because the question doesn't specify a language—apologies if this is not your native dialect.)

- 239,200
- 50
- 490
- 574
-
This didn't seem to work for me, I got it working but my datagridview didn't have a `=HitTestInfo.Nowhere` i had to change it to..... `If myDataGridView.HitTest(e.X, e.Y) Is myDataGridView.HitTest(e.X, e.Y) Then`... works as intended, but not 100% sure why it works. First HitTest code implemented. – nora Jun 06 '16 at 10:03
-
1@nora The code you wrote doesn't really make any sense. It should not have worked. The [`Is` operator](https://msdn.microsoft.com/en-us/library/kb136x1y.aspx) compares the types of two reference variables. So all you're doing there is checking that the `HitTest` property returns a value of the same type as the...`HitTest` property. It's like saying `If True = True`. – Cody Gray - on strike Jun 07 '16 at 09:53
-
@nora (continued) In reality, the [`HitTest` property](https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.hittest.aspx) returns a value of type `HitTestInfo`. [`HitTestInfo`](https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.hittestinfo.aspx) is a non-inheritable class that contains, among other things, a static field named `Nowhere`. This is the field that you need to compare against. I suppose what's tripping you up is that the `HitTestInfo` class is a *nested* class of `DataGridView`. I've updated my answer to explicitly qualify it. – Cody Gray - on strike Jun 07 '16 at 09:54
-
I was thinking about this before, are there not perhaps two 'HitTests', one for the Blank Space, and One for the Cells occupied space?.. So the HitTest above is saying `If Blank Space Is Blank Space Then`.. Where the cell version would be something like `If Cell Space Is Cell Space Then`.. maybe?.. just wondering why mine works with a `True = True` situation ? If I click a Cell the highlight stays, if i click a blank space it goes away. – nora Jun 07 '16 at 14:47
-
Do not call ClearSelection too soon! – TaW Jun 30 '16 at 16:39
-
2@TaW That comment would be more helpful if you specified what you meant by "too soon". – Cody Gray - on strike Jul 01 '16 at 07:17
-
3Well, I found that e.g. after filling a DGV in the constructor __is__ 'too soon'. Moving the ClearSelection to Form_Shown works fine.. Not sure what the exact rule is; maybe something like 'after layout'? I added the note as there are many comments on similar post that find ClearSelection doesn't work for them. So adding it to theis high-voted answer seemd like a good idea. – TaW Jul 01 '16 at 07:28
-
Sorry to revisit an old thread but I ran into the same problems as @nora and, just for the benefit of future visitors, I think there's a syntactic issue with the code provided by Cody. You can't use `If myDataGridView.HitTest(e.X, e.Y) = DataGridView.HitTestInfo.Nowhere Then` because : Operator '=' is not defined for types 'DataGridView.HitTestInfo' - I believe this line should be written thus : `If myDataGridView.HitTest(e.X, e.Y).Type = DataGridViewHitTestType.None Then` (basically a VB version of tinmac's C# version below...) – Alan O'Brien Nov 16 '22 at 14:47
C# version:
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
DataGridView.HitTestInfo hit = dgv_track.HitTest(e.X, e.Y);
if (hit.Type == DataGridViewHitTestType.None)
{
dgv_track.ClearSelection();
dgv_track.CurrentCell = null;
}
}

- 2,357
- 3
- 25
- 41
i found out why my first row was default selected and found out how to not select it by default.
By default my datagridview was the object with the first tab-stop on my windows form. Making the tab stop first on another object (maybe disabling tabstop for the datagrid at all will work to) disabled selecting the first row

- 582
- 5
- 18
-
This actually solved my problem too. For some strange reason changing the `TabStop` property to `false` seems to load the form without a selected `DataGridView` cell/index. – Apostrofix Jun 18 '14 at 07:10
-
This doesn't work. If you set a breakpoint on the SelectionChanged event and enable .NET Framework Source Stepping, you can see a call from OnHandleCreated() to MakeFirstDisplayedCellCurrentCell(). This is why it happens, not because it can be "tabbed" into. – computerGuyCJ Jul 24 '15 at 18:26
i have ran into the same problem and found a solution (not totally by myself, but there is the internet for)
Color blue = ColorTranslator.FromHtml("#CCFFFF");
Color red = ColorTranslator.FromHtml("#FFCCFF");
Color letters = Color.Black;
foreach (DataGridViewRow r in datagridIncome.Rows)
{
if (r.Cells[5].Value.ToString().Contains("1")) {
r.DefaultCellStyle.BackColor = blue;
r.DefaultCellStyle.SelectionBackColor = blue;
r.DefaultCellStyle.SelectionForeColor = letters;
}
else {
r.DefaultCellStyle.BackColor = red;
r.DefaultCellStyle.SelectionBackColor = red;
r.DefaultCellStyle.SelectionForeColor = letters;
}
}
This is a small trick, the only way you can see a row is selected, is by the very first column (not column[0], but the one therefore). When you click another row, you will not see the blue selection anymore, only the arrow indicates which row have selected. As you understand, I use rowSelection in my gridview.

- 582
- 5
- 18
In VB.net use for the Sub:
Private Sub dgv_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles dgv.MouseUp
' deselezionare se click su vuoto
If e.Button = MouseButtons.Left Then
' Check the HitTest information for this click location
If Equals(dgv.HitTest(e.X, e.Y), DataGridView.HitTestInfo.Nowhere) Then
dgv.ClearSelection()
dgv.CurrentCell = Nothing
End If
End If
End Sub

- 51
- 3
- 9