DataGridViewの内容がDataTableに反映される・書き込みされるタイミングについて

DataGridViewの内容がDataTableに反映されるのはDataGridViewの起こすどのイベントより遅いから、自分で書き込んでやることにした
1
H.J. @qorph

だれかがどこかに書いているかもしれないけれどDataGridViewについてつらつら書きます

2015-05-21 20:03:17
H.J. @qorph

C#やVBつかってるとDataSetっていうのがあって、このデータベースは、テーブルの各カラムごとに型を決められます。 pic.twitter.com/fWRJxVBkXB

2015-05-21 20:08:54
拡大
H.J. @qorph

フォームアプリケーションにはDataGridViewっていうコントロールもあって、これをフォームに配置すると、DataTableの中がのぞけます。DataGridViewにユーザーが入力すると、BindingSourceを通じてDataTableの中身も更新されます。便利です。

2015-05-21 20:10:49
H.J. @qorph

DataTableはこういう風にユーザーの入力を受け付けやすく、SQL文で検索も出来る優れもので、先述の型をbooleanにしておけば、こんな塩梅にチェックボックスが並べられます。 pic.twitter.com/YGHHSuVauq

2015-05-21 20:18:38
拡大
H.J. @qorph

正直こういう風な名前のリストを作って、選択・非選択だけチェックしたければ、ListBoxのSelectionmodeプロパティをMultiSimpleにすればいいんですけれど、複数の選択項目がある場合、データベースに接続したい場合は、DataGridView便利ってわけです。

2015-05-21 20:23:18
H.J. @qorph

便利なDataGridViewですが、ここからが問題なんです。 選択された内容が変わった瞬間、裏でその結果を使い始めるコードを書きたいことがあると思います。

2015-05-21 20:25:32
H.J. @qorph

ListBoxなら、SelectedIndexChangedイベントを拾えば、確実に動作させることができますが、DataGridViewはどうも上手く拾えていないように見えるんです。他のセルをいじり始めたら思い出したように処理が始まったりする。これでは困ります。

2015-05-21 20:28:21
H.J. @qorph

CellClick、CellContentClick、CellEndEdit、CellMouseClick、CellMouseDown、CellMouseUp、CellParsing、CellValueChanged、全部駄目です。なぜでしょう。

2015-05-21 20:30:30
H.J. @qorph

ヒントはMSDNにあります。DataGridViewの値が変更されると、その後DataTableはViewの内容に沿って変更されるわけですが、先ほどあげたイベントは、すべてDataTableの更新前に起こるイベントなのです。

2015-05-21 20:32:25
H.J. @qorph

【んで、どうするか】 書き込みが起こる前なら書き込んじゃいましょう。 今回はセレクトボックスについてのみ処理したいので、CellMouseUpの呼び出す関数として以下を書きました。

2015-05-21 20:40:39
H.J. @qorph

dataSet1.DataTable1.Rows[dGV1.CurrentCell.RowIndex][dGV1.CurrentCell.ColumnIndex] = !(Convert.ToBoolean(dGV1.CurrentCell.Value));

2015-05-21 20:41:22
H.J. @qorph

もちろんCurrentCellがBooleanなCellかは何らかの方法でケアしておけばOKです。DataGridViewのValueはまだ更新されていないので、Booleanをひっくり返してます。

2015-05-21 20:43:39
H.J. @qorph

DataGridViewはこれで更新した結果をDataTableから自動で読み取って、フォームに反映してくれます。 最後に。 ①嬉しい副作用:セレクトボックスがあるセルの、セレクトボックス以外の部分を押しても動きます! ②残念な副作用:dGVが手動ソートされてるとつかえませーん

2015-05-21 20:45:57
H.J. @qorph

P.S. DataGridViewの内容がDataTableに転送されるのは、DataRowがEndEditされたときだという情報がありました(ただし個人サイト) でも、EndEditするためにフォーカスを別の行または別のコントロールに移すコードを書いても解決しませんでした。

2015-05-21 21:02:53