DataGridViewのCheckBoxColumnの値の取得について

タグの編集
投稿者 N88-Basic  (社会人) 投稿日時 2019/8/12 09:52:55
Windows 10 Home(64 1903) + Visual Basic 2017 にて DataGridView の CheckBoxXokumn の値の取得方法がわかりません。目的は行の選択に利用したいと思っております。 MultiSelect で処理してもいいと思いますが、操作上、Ctrl キーなどの併用が必要なので使いにくいと感じています。

現状は、
 DataGridview.Rows(x).Cells("mark").Value で対応しようとしていますがうまく処理できません。
 truevalue や falsevalue に値をセットしても正常に取得できません。

対処方法をご存じでしたらご教授ください。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2019/8/12 12:50:36
> CheckBoxXokumn 
DataGridViewCheckBoxColumn や
DataGridViewCheckBoxCell の事でしょうか。

データバインドしているのであれば、バインド元の DataTable に対して、
Boolean 型の列を設けておくのが、最も手間がかからないと思います。(Linq との相性も良い)
この場合、DataGridView1.Rows を列挙するのではなく、
バインド元の DataTable の Rows を列挙するようにします。


バインドしなくてもできなくは無いですが、DataGridView の列をクリックしてソートされた場合、
どっちにていも行番号単位では取得できず、DataGridViewRow に遡って
各セルを参照しなおす必要がありますね。


> うまく処理できません。
どう処理しているかにもよりますが、2 つ確認したい点が。


(1) RowHeadersVisible を True にしておいた場合、各行の左端にある行ヘッダー列は、
 [ ▶ ] になっていますか? それとも
 [...🖊] になっていますか?
 後者は値が確定する前なので、前者の状態にしてからアクセスする必要があります。
 
(2) 実際、DataGridView1("mark", rowIndex).Value から返される Object 値は何になっていますか?
 DBNull.Value なのか、Nothing なのか "" なのか True なのか "True" なのか 1 なのか…。
 データ型も重要なところなので、TypeName 関数などで確認してみてください。
投稿者 N88-BASIC  (社会人) 投稿日時 2019/8/15 10:17:21
 魔界の仮面弁士 さま、ご回答ありがとうございます。

一番の問題点は、

>[ ▶ ] になっていますか? それとも
>[...🖊] になっていますか?
 後者は値が確定する前なので、前者の状態にしてからアクセスする必要があります。

 後者の状態で値を取得しようとしていたために目的とした処理(チェック項目の列を一括処理する)ができなかったようです。

ご指摘のTypeName 関数で調べてみると、チェックを操作する前は Boolean ですが、操作すると以後は string でした、値そのものは、true / false でした。

  Dim obj As Object = Datagrideview1("mark", 1).Value
  Textbox1.Text = TypeName(obj) + ":" + obj.ToString

チェック項目しか操作しないので、確定前に次の処理を選択してしまいそうですので、確実性を増すために、別の処理に変えてみたいと思います。

今後ともよろしくお願いいたします。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2019/8/15 12:11:33
> チェックを操作する前は Boolean ですが、操作すると以後は string でした、値そのものは、true / false でした。

DataGridViewCheckBoxColumn の TrueValue As Object プロパティに、
Boolean の True ではなく、
String の "True" を渡していたのでは無いでしょうか。


> 後者の状態で値を取得しようとしていたため
チェックされたら、即時に値を確定させてしまいましょう。
https://dobon.net/vb/bbs/log3-43/26073.html
投稿者 ルパン  (社会人) 投稿日時 2019/8/16 16:56:43
横からスミマセン。
DataGridViewのCurrent​Cell​Dirty​State​Changedイベントで、「Dirty​」っていう英語を使っていますが、
ここでいう「Dirty​」とはどういう意味なのでしょうか?
「汚れた状態」ではないですよね?
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2019/8/16 18:39:12
> ここでいう「Dirty​」とはどういう意味なのでしょうか?

ざっくり言えば、メモリ上にあるデータは編集済みであるけれども、
元データにはまだ反映されていない状態を指す言葉です。

また、オブジェクトの状態を記録しておき、何らかのタイミングで
変化をチェックする仕組みを、dirty check と呼ぶことがあります。


> 「汚れた状態」ではないですよね? 

そのまま ダーティ状態 と呼ぶこともありますが、
ニュアンス的には、途中の状態 といった感じでしょうか。


たとえば…既存の Excel ファイルを開いてワークシートを編集してから
アプリケーションを閉じようとすると、保存確認のダイアログが表示されますよね。

まだ変更結果は、元の Excel ファイルに反映されていないわけですが、
このときの Excel の状態を指して dirty であるということがあります。


データベースにおいて、コミット前の情報が他から参照できることを指して
dirty read と呼ぶことがありますが、これも同じ意味です。


Current​Cell​Dirty​State​Changed イベントの場合は、
現在のセルの内容が変更された直後で、
その変更が確定される直前で通知されたりしますね。
投稿者 N88-BASIC  (社会人) 投稿日時 2019/8/17 12:47:10
魔界の仮面弁士 さま、ご回答ありがとうございます。

ご案内いただいた回答内容、並びにリンク先を参考に、EndEdit にて解決できました。
また、値はご指摘のとおり String 型のようでした。型変換(Visual Studio のヒントを利用)で bool 型に変換できました。

ルパンさんへ
「Dirty」というのはネイティブの方には変に感じないのでしょうか。イメージは理解できますが直訳されると何?と思ってしまうかもしれませんね。

今後ともよろしくお願いいたします。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2019/8/19 10:25:20
参考情報として、下記も紹介しておきます。
https://blogs.msdn.microsoft.com/jpsql/2013/09/29/ado-net-datagridview-datatable-2120/