チェック ボックスの数が予想と異なる場合、2 つの原因が考えられます。最も可能性が高いのは、フォーカスを失ったときに datagridview 編集コントロールが値をコミットする方法が原因で、チェック ボックス列の値がチェック ボックスの状態よりも遅れているという事実です。
これを修正するには、MSDN で説明されているように CurrentCellDirtyStateChanged イベントを処理します。
したがって、コードは次のようになります。
Sub dataGridView1_CurrentCellDirtyStateChanged( _
    ByVal sender As Object, ByVal e As EventArgs) _
    Handles dataGridView1.CurrentCellDirtyStateChanged
    If dataGridView1.IsCurrentCellDirty Then
        dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
    End If 
End Sub
そして、CellValueChangedHander は次のように変更されます。
Public Sub dataGridView1_CellValueChanged(ByVal sender As Object, _
    ByVal e As DataGridViewCellEventArgs) _
    Handles dataGridView1.CellValueChanged
    If dataGridView1.Columns(e.ColumnIndex).Name = "CheckBoxes" Then 
        Dim count1 As Integer = 0
        For Each row As DataGridViewRow In dgvAtt.Rows
            If row.Cells("CheckBoxes").Value IsNot Nothing And row.Cells("CheckBoxes").Value = True Then
                count1 += 1
            End If
        Next
        txtCnton.Text = count1
    End If 
End Sub 
上記のコードでは、誤ったカウントの 2 番目に考えられる原因にも対処しています。コードでは、セル配列内のインデックスで datagridview セルを参照します。これが最善の方法であるということはほとんどありません。代わりに、各列には、インデクサーで使用できる名前があります。