DOBON.NET DOBON.NETプログラミング掲示板過去ログ

DataGridViewCheckBoxCell 余白クリックでのON/OFF切替

環境/言語:[WinXP, 7 .NET Framework 4.0]
分類:[.NET]

いつもお世話になっております。


http://d.hatena.ne.jp/tatsuparu/20101129/1291018310

を参考に、以下のようなコードを作成して
表題のような動作を実装しようとしました。


    Private Sub dgv_CellMouseClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles dgv.CellMouseClick
        Try
            'イベント発生位置のセルを取得
            Dim cell As DataGridViewCell = dgv(e.ColumnIndex, e.RowIndex)

            'チェックボックス型?
            If TypeOf cell Is DataGridViewCheckBoxCell Then

                'キャスト
                Dim cCell As DataGridViewCheckBoxCell = DirectCast(cell, DataGridViewCheckBoxCell)

                If cCell.Value = Nothing Or cCell.Value = False Then
                    'チェックONではない場合:ONにする
                    cCell.Value = True
                Else
                    'チェックONの場合:OFFにする
                    cCell.Value = False
                End If
            End If

            'リフレッシュ
            dgv.RefreshEdit()
        Catch ex As Exception

        End Try
    End Sub


実際に動かしたところ、セルの余白部分を連続クリックした場合に反応が鈍いです。
2回/秒程度のクリックなら何とかクリックのたびにチェックON/OFFが切り替わりますが
それ以上の速度になると、チェックが切り替わらないことが度々あります。

DataGridViewCheckBoxColumn.ThreeStateプロパティは念のため
明示的にFalseに設定しています。

何か抜けているコードや設定があるのでしょうか。
それともDataGridViewの性能の限界なのでしょうか。
(端末スペックは十分にあるものとしてお考え下さい)

以上です。よろしくお願いします。
■No29639に返信(さちもさんの記事)
> それ以上の速度になると、チェックが切り替わらないことが度々あります。
コントロールパネルから、マウスのダブルクリック間隔を
最短値にすれば、ある程度は改善されるかと思います。

短時間で連続クリックした場合、CellMouseClick ではなく、
CellMouseDoubleClick に流れて行ってしまい、ズレが生じるようで。
http://msdn.microsoft.com/ja-jp/library/ms171543.aspx


> 何か抜けているコードや設定があるのでしょうか。
MouseUp あたりの方が良いのかも。

Public Class Form1
    Private WithEvents dgv As DataGridView
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
        dgv = New DataGridView() With {.Dock = DockStyle.Fill}
        Controls.Add(dgv)
        dgv.Columns.Add(New DataGridViewTextBoxColumn() With {.Name = "ID", .HeaderText = "ID"})
        dgv.Columns.Add(New DataGridViewCheckBoxColumn() With {.Name = "CHK1", .HeaderText = "CHK"})
        dgv.Columns.Add(New DataGridViewCheckBoxColumn() With {.Name = "CHK2", .HeaderText = "CHK", .TrueValue = 1, .FalseValue = 0})
        dgv.RowCount = 10
    End Sub

    Private Sub dgv_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) Handles dgv.MouseUp
        Dim ht = dgv.HitTest(e.X, e.Y)
        If ht.Type = DataGridViewHitTestType.Cell Then
            Dim cell = TryCast(dgv(ht.ColumnIndex, ht.RowIndex), DataGridViewCheckBoxCell)
            If cell IsNot Nothing Then
                cell.Value = If(cell.Value = cell.FalseValue, If(cell.TrueValue, True), cell.FalseValue)
                dgv.EndEdit()
            End If
        End If
    End Sub
End Class

DOBON.NET | プログラミング道 | プログラミング掲示板