I was having issues with this myself. I was using the following code, and I couldnt figure out why it wasn't working right all of the time.
(Note that my code is in VB, but I think the same concept would apply to other .NET languages)
Dim check As DataGridViewCheckBoxCell = DataGridView1.Rows(i).Cells("columnNameHere")
If check.Value = check.TrueValue Then
'do stuff
End If
I then realized that it was because the underlying value of the cell isnt changed until it loses focus. I think DGVs always behave like this, but it can be easy to forget.
My solution was to simply add a little bit of code to the data grid views on click event handler. When the user clicks the checkbox, all it does is shift the focus elsewhere. I shifted the focus to a label so that it doesnt have any unintended consequences. (Ex: if you shift it to a button the user might be surprised when they press enter and a random button activates.) Depending on what else is in your DGV, you may want to check the column index of the event so that you are only doing this for the checkbox columns. All of the other columns in my DGV are read only anyways, so it didnt matter in my case.
Private Sub DataGridView1_CellContentClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
Label1.Focus()
End Sub
If the code in question was contained in a button, the focus would already be shifted away from the DGV to the button, so this wouldn't be an issue. In my case, the code was activated by a timer - meaning that the DGV cell in question wouldn't necissarily lose focus before the timer fired.