DataGridViewの内容がDataTableに反映される・書き込みされるタイミングについて
C#やVBつかってるとDataSetっていうのがあって、このデータベースは、テーブルの各カラムごとに型を決められます。 pic.twitter.com/fWRJxVBkXB
2015-05-21 20:08:54フォームアプリケーションにはDataGridViewっていうコントロールもあって、これをフォームに配置すると、DataTableの中がのぞけます。DataGridViewにユーザーが入力すると、BindingSourceを通じてDataTableの中身も更新されます。便利です。
2015-05-21 20:10:49DataTableはこういう風にユーザーの入力を受け付けやすく、SQL文で検索も出来る優れもので、先述の型をbooleanにしておけば、こんな塩梅にチェックボックスが並べられます。 pic.twitter.com/YGHHSuVauq
2015-05-21 20:18:38正直こういう風な名前のリストを作って、選択・非選択だけチェックしたければ、ListBoxのSelectionmodeプロパティをMultiSimpleにすればいいんですけれど、複数の選択項目がある場合、データベースに接続したい場合は、DataGridView便利ってわけです。
2015-05-21 20:23:18便利なDataGridViewですが、ここからが問題なんです。 選択された内容が変わった瞬間、裏でその結果を使い始めるコードを書きたいことがあると思います。
2015-05-21 20:25:32ListBoxなら、SelectedIndexChangedイベントを拾えば、確実に動作させることができますが、DataGridViewはどうも上手く拾えていないように見えるんです。他のセルをいじり始めたら思い出したように処理が始まったりする。これでは困ります。
2015-05-21 20:28:21CellClick、CellContentClick、CellEndEdit、CellMouseClick、CellMouseDown、CellMouseUp、CellParsing、CellValueChanged、全部駄目です。なぜでしょう。
2015-05-21 20:30:30ヒントはMSDNにあります。DataGridViewの値が変更されると、その後DataTableはViewの内容に沿って変更されるわけですが、先ほどあげたイベントは、すべてDataTableの更新前に起こるイベントなのです。
2015-05-21 20:32:25【んで、どうするか】 書き込みが起こる前なら書き込んじゃいましょう。 今回はセレクトボックスについてのみ処理したいので、CellMouseUpの呼び出す関数として以下を書きました。
2015-05-21 20:40:39dataSet1.DataTable1.Rows[dGV1.CurrentCell.RowIndex][dGV1.CurrentCell.ColumnIndex] = !(Convert.ToBoolean(dGV1.CurrentCell.Value));
2015-05-21 20:41:22もちろんCurrentCellがBooleanなCellかは何らかの方法でケアしておけばOKです。DataGridViewのValueはまだ更新されていないので、Booleanをひっくり返してます。
2015-05-21 20:43:39DataGridViewはこれで更新した結果をDataTableから自動で読み取って、フォームに反映してくれます。 最後に。 ①嬉しい副作用:セレクトボックスがあるセルの、セレクトボックス以外の部分を押しても動きます! ②残念な副作用:dGVが手動ソートされてるとつかえませーん
2015-05-21 20:45:57P.S. DataGridViewの内容がDataTableに転送されるのは、DataRowがEndEditされたときだという情報がありました(ただし個人サイト) でも、EndEditするためにフォーカスを別の行または別のコントロールに移すコードを書いても解決しませんでした。
2015-05-21 21:02:53