DataGridViewのチェックボックスについて

解決


fumofumofit  2009-11-30 11:09:23  No: 146586  IP: 192.*.*.*

開発環境:  WinXP(SP3) VB2005 Oracle9i

DataGridViewにあるテーブルデータを
バインドで表示して、チェックボックスの
チェックを入れた行のみ更新処理をするものを
作成しています。
そして、11件以上はチェック出来ないように
制御がしたいのですが上手くいきません。
ご教授願います。

上手くいかないのは、11件目をチェックした時に、
エラーメッセージを出力した後にチェックボックスの
チェックをコードではずしているのですが、画面の表示
では他のセルに移動しないとチェックが入ったままに
なり、他のセルに移動せずにチェックボックスを
クリックするとチェックがはずせて再度チェックを
入れると11件以上チェックが出来てしまいます。

-- コード --

Private Sub DataGridView_Tab1_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView_Tab1.CellValueChanged
'★☆★☆★ チェックボックス件数 ★☆★☆★

If DataGridView_Tab1.RowCount = 0 Then
    Exit Sub
End If

If DataGridView_Tab1(0, e.RowIndex).Value = 1 Then
    Chk_Count += 1
    DataGridView_Tab1("品番ID", e.RowIndex).Style.BackColor = Color.Orange
Else
    Chk_Count -= 1
    If e.RowIndex Mod 2 = 0 Then
        DataGridView_Tab1("品番ID", e.RowIndex).Style.BackColor = Color.White
    Else
        DataGridView_Tab1("品番ID", e.RowIndex).Style.BackColor = G_ARGB
    End If
End If

If Chk_Count > 10 And Cnt_FLg = True Then
    MessageBox.Show("11件以上はチェックできません", 
    My.Application.Info.Title, MessageBoxButtons.OK, MessageBoxIcon.Error)
    DataGridView_Tab1(0, e.RowIndex).Value = 0
    DataGridView_Tab1.CurrentCell = DataGridView_Tab1(2, e.RowIndex) -①
End If

End Sub

Private Sub DataGridView_Tab1_CurrentCellDirtyStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataGridView_Tab1.CurrentCellDirtyStateChanged
'★☆★☆★ セル変更コミット ★☆★☆★

If DataGridView_Tab1.CurrentCellAddress.X = 0 AndAlso _
            DataGridView_Tab1.IsCurrentCellDirty Then
    'コミットする
    DataGridView_Tab1.CommitEdit(DataGridViewDataErrorContexts.Commit)
End If

End Sub

※G_ARGBは事前に設定している色です。

-①はチェックの値を0にした後に別のセルに移動すれば解決するかと思い
追加したのですが、これでは永久にエラーメッセージが表示される
ようになりうまくいきませんでした。

チェックボックスの画面のチェックを消す方法があればご教授願います。

不足又は不明確なところがございましたらご指摘のほどお願いします。

編集 削除
 2009-11-30 22:43:04  No: 146587  IP: 192.*.*.*

If Chk_Count > 10 And Cnt_FLg = True Thenのところで、
DataGridView_Tab1(0, e.RowIndex).Value = 0にしているけど、
Chk_Countをデクリメントしなくてもいいの?

編集 削除
fumofumofit  2009-12-01 09:54:22  No: 146588  IP: 192.*.*.*

あ  さんアドバスありがとうございます。

>If Chk_Count > 10 And Cnt_FLg = True Thenのところで、
>DataGridView_Tab1(0, e.RowIndex).Value = 0にしているけど、
>Chk_Countをデクリメントしなくてもいいの?

上記の場所でChk_Countをデクリメントすると
DataGridView_Tab1(0, e.RowIndex).Value = 0 後に
発生する DataGridView_Tab1_CellValueChanged イベントで
さらにデクリメントされてしまい本来Chk_Count=10
になるところがChk_Count=9になってしまい解決には至りませんでした。

DataGridView_Tab1(0, e.RowIndex).Value = 0  後の
DataGridView_Tab1_CellValueChanged イベントでChk_Count=10
になりさらに、画面でエラーメッセージが出たチェックボックスの
チェックをはずした時に、DataGridView_Tab1_CellValueChanged イベント
が発生しChk_Count=9になる為に、再度同一のチェックボックスを
チェックすると実際は11件目なのに10件目の判定となり
10件以上チェック出来るみたいなので、
画面でエラーメッセージが出たチェックボックスの
チェックをはずした時のDataGridView_Tab1_CellValueChanged イベント
でChk_Count=10になるように出来ないか思考錯誤中です。

1.DataGridView_Tab1(0, e.RowIndex).Value = 0後の
    DataGridView_Tab1_CellValueChanged イベントが走らないようにする。

  結果:エラーメッセージが出たチェックボックスのチェックを
        はずした時は上手くいくが、チェックをはずさなかったら
        Chk_Countはデクリメントされずに11件のままになり、
        10件目のチェックをはずした時にエラーメッセージが
        表示されてしまう。

以上現状はこのような状態です。

編集 削除
 2009-12-01 14:31:28  No: 146589  IP: 192.*.*.*

>1.DataGridView_Tab1(0, e.RowIndex).Value = 0後の
>    DataGridView_Tab1_CellValueChanged イベントが走らないようにする。

どうやってイベントが走らないようにしているのかな?
私なら、ない頭を使って、例えば、
・フォーム内変数等にフラグを持たせる(通常False)。
・CellValueChangedイベントが発生したとき、
  このフラグがTrueの場合はイベント処理を行わない。
  それ以外の場合は、チェックボックスのチェック数を計算する。
  チェックが11個になったら、このフラグをTrueにしてからエラーメッセージを表示し、
  DataGridView_Tab1(0, e.RowIndex).Value = 0を行う。
  このフラグを立てた場合はフラグをFalseに戻す
としてみるかも?
あるいは、Chk_Count=10になった時点でチェックボックスのチェックができないようにしちゃうけど。

編集 削除
むだ  2009-12-01 21:31:52  No: 146590  IP: 192.*.*.*

バkあちんに御教授しても無駄。
ばka.co.jp

編集 削除
fumofumofit  2009-12-02 09:47:47  No: 146591  IP: 192.*.*.*

あ  さん
アドバイスありがとうございます。

>・フォーム内変数等にフラグを持たせる(通常False)。
>・CellValueChangedイベントが発生したとき、
>  このフラグがTrueの場合はイベント処理を行わない。
>  それ以外の場合は、チェックボックスのチェック数を計算する。
>  チェックが11個になったら、このフラグをTrueにしてからエラーメッセージを表示し、
>  DataGridView_Tab1(0, e.RowIndex).Value = 0を行う。
>  このフラグを立てた場合はフラグをFalseに戻す

1.は上記アドバイスに近いことをやりました。
その結果うまくいきませんでした。

上記のアドバイス通りしたのですが上手くいきませんでした。

やはりDataGridView_Tab1(0, e.RowIndex).Value = 0
ではチェックボックスのチェックが他のセルに移動しないと
はずれないのです。(画面のチェック)
DataGridView_Tab1(0, e.RowIndex).Value = 0で、マススで
チェックボックスをクリックしてチェックをはずすのと同じ
処理が出来ると思っていたのですがどうも違うようです。

マウスでチェックをはずすのと同じ処理はコードでは無理なのでしょうか?

>あるいは、Chk_Count=10になった時点でチェックボックスのチェックができないようにしちゃうけど。

チェックができないようにするにはどうすれば簡単にできますか?

例えば
・Chk_Count=10になった時点(CellValueChangedでChk_Countをインクリメントした直後)で
  現在チェックが入っていないセルのReadOnlyをTrueにして
  Chk_Count<10になった時点で全てのセルのReadOnlyをFalseにする。
で実現できそうなのですが・・・

編集 削除
fumofumofit  2009-12-02 10:21:49  No: 146592  IP: 192.*.*.*

あ  さん
解決しました。
ありがとうございました。

解決コードは下記です。

CellValueChangedイベント
'★☆★☆★ チェックボックス件数 ★☆★☆★
If DataGridView_Tab1.RowCount = 0 Then
    Exit Sub
End If

If Cnt_Flg = True Then Exit Sub

If DataGridView_Tab1(0, e.RowIndex).Value = 1 Then
    Chk_Count += 1
    DataGridView_Tab1("品番ID", e.RowIndex).Style.BackColor = Color.Orange
Else
    If Cnt_Flg2 = False OrElse Chk_Row <> e.RowIndex Then
        Chk_Count -= 1
        If e.RowIndex Mod 2 = 0 Then
            DataGridView_Tab1("品番ID", e.RowIndex).Style.BackColor = Color.White
        Else
            DataGridView_Tab1("品番ID", e.RowIndex).Style.BackColor = G_ARGB
        End If
    End If
End If

If Chk_Count > 10 Then
    Cnt_Flg = True
    MessageBox.Show("11件以上はチェックできません", My.Application.Info.Title, MessageBoxButtons.OK, MessageBoxIcon.Error)
    DataGridView_Tab1(0, e.RowIndex).Value = 0
    Chk_Count -= 1

    If e.RowIndex Mod 2 = 0 Then
        DataGridView_Tab1("品番ID", e.RowIndex).Style.BackColor = Color.White
    Else
        DataGridView_Tab1("品番ID", e.RowIndex).Style.BackColor = G_ARGB
    End If

    Cnt_Flg = False
    Cnt_Flg2 = True
    Chk_Row = e.RowIndex
    Exit Sub
End If

Cnt_Flg2 = False
Chk_Row = 0

編集 削除