- - PR -
DataGridViewの編集内容がDatasetに格納されるタイミング
1
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-05-29 14:45
お世話になります。
Datasetを使用してDataGridViewを表示し、DataGridView上で編集した値で Datasetを書き換えてDBに反映させるという処理を行おうとしています。 DataGridView上で編集した値が勝手にDatasetに格納されると思っていたのですが、 格納されている場合とされていない場合があるようです。 そのためDataGridView1_CellEndEditイベントで明示的にDatasetに値を設定しなければ ならないと思っておりまして以下のようにしましたが、Datasetに反映してくれないです。 <DataGridView1_CellEndEditイベント>↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ Private _GridViewDataSet As New Data.DataSet("T_XXX") Dim wkDataRow1 As DataRow = Nothing Dim wkRecKey As Integer = 0 Dim Dview As DataView = Nothing wkRecKey = 主キー(番号)←グリッドのレコードが持っている Dataset主キーも設定済み Dview = New DataView(_GridViewDataSet.Tables(Constant.CONST_DATASET_1), _ "ID_RECNO" + "=" + Convert.ToString (wkRecKey), "",DataViewRowState.CurrentRows) 'DATASETを更新 wkDataRow1 = _GridViewDataSet.Tables("T_XXX").Rows.Find(wkRecKey) wkDataRow1("I_項目名") = 更新したい値(グリッドのセル値) ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 「DataGridViewのValueで更新すれば良いじゃん」と思われますでしょうが、 そもそもなぜDatasetの値がほしいかといいますと、 例えばレコードが10件を取得したとして、モードによって表示が5件だったり1件だったりと レコードを隠す処理があり、更新の際に対象となるデータは10件全てだからです。 そのときの表示が1件だとしても全10件のデータがほしいのです。 (もちろん10件中の編集の有無を見て更新しますが) という具合でDataGridViewからDatasetに データを反映させる術をどなたかアドバイス願います。 Datasetに自動で反映されている場合もあるのですが、その機会はいつなのかも疑問です。 [ メッセージ編集済み 編集者: ピン 編集日時 2007-05-29 14:49 ] [ メッセージ編集済み 編集者: ピン 編集日時 2007-05-29 14:51 ] [ メッセージ編集済み 編集者: ピン 編集日時 2007-06-03 13:48 ] | ||||||||||||
|
投稿日時: 2007-05-29 16:22
こんにちは
まず CellEndEdit で処理する必要はないはずです。 ピンさんのおっしゃる通り、バインドしているのならば、 「DataGridView上で編集した値が勝手にDatasetに格納される」は正しいです。 しかしながら、格納されるタイミングに落とし穴があります。 (私も昔はまりました) おそらくなんですが、追加行以外のデータを変更した後、 他の行にフォーカスを移動していない状態で、 DataSet のデータを参照すると更新前になっているという事象ではないですか? だと仮定して話を進めますが、行の編集がまだ確定されていないのが原因です。 DataGridView の場合、セルの値を変更した後、 別の行にフォーカスが移動することで行の更新が確定されます。 (逆に、行の更新が確定される前は Esc キーで元に戻すことができます) これを解決するには、DataSet のデータを参照する前に、 行の編集を強制的に確定してやる必要があります。 現在行の DataBoundItem (DataRowView型) のEndEdit を呼び出します。
あと、ちょっと本題とは違いますが
ここの意味がよくわかりませんでした。 せっかく DataSet 使っているのに、DataAdapter を使って更新しないんですか? DataAdapter を使用すれば、表示されているのが何行であろうと DataSet そのものを更新してくれるはずですが。 | ||||||||||||
|
投稿日時: 2007-05-29 17:23
いつもありがとうございます。
んー。その事象ではないような気がします。エンターで確定してもDatasetには 入っていないように見えます。KIさんがおっしゃる確定の処理も必要だとは思うのですが、 Datasetに書き込めていないのでなく、読めていないような気もしてきました。 といいますのも、グリッドで値を変更してから以下のようにDataViewクラスを使用して再表示すると変更した値が表示されています。 Dview = New DataView(_GridViewDataSet.Tables("T_XXX"), _ "", "", DataViewRowState.CurrentRows) DataGridView1.DataSource = Dview ちなみにDatasetは pDataSetTable = _GridViewDataSet.Tables("T_XXX")・・・引数でもらう wk_ChkStr = Convert.ToString(pDataSetTable.Rows(y)(x)) でアクセスしてますが、編集前の値が取れてしまいます。
DBの更新はDAOを使った共通関数を使うという制約があります。 取得の際も、SQL文でテーブルの値を持ってくるだけでなくXML等を読み込んでDatasetに 取り込んでいます。 [ メッセージ編集済み 編集者: ピン 編集日時 2007-05-29 17:33 ] | ||||||||||||
|
投稿日時: 2007-05-29 19:56
十中八九これだと思ったんですけど、外しちゃいましたかね。 しつこいようで悪いんですが、「エンターで確定」ってセルの編集確定ですよね。 私は行の編集確定(別の行にフォーカスを移動させることで確定)の話をしましたが、 そこは勘違いされていませんよね? 「pDataSetTable.Rows(y)(x)) 」では取れないとのことですが、 「pDataSetTable.Rows(y)(x, DataRowVersion.Proposed)) 」でも取れませんか? これで取れるなら、私の指摘した事象だと思うのですが…取れないなら違いますね。 それでないとすると、正直思いつかないですね… 「レコードを隠す処理」が悪さをしてるとかでしょうか。 ただ、いずれにせよ、CellEndEdit で処理するのは少し強引すぎますし、 バインドで設定されるのに、さらに設定するような処理を書いていると 思いがけない動作の原因になりかねないと思います。
しっくりはきませんが、事情は理解しました。 先の書き込みに「『DataGridViewのValueで更新すれば良いじゃん』」とありましたが、 DataGridView の値を元にして更新するのは本来のあり方ではないと思います。 DataGridView はあくまで DataSet を編集するためのUI部品なのですから、 アプリケーションは DataSet を元に処理をすべきと思います。 | ||||||||||||
|
投稿日時: 2007-05-29 21:01
大変申し訳ないのですが、ニヤミスのにおいがしてきました。現在検証中です。
今日は遅いので結果は明日にでもお知らせします。 | ||||||||||||
|
投稿日時: 2007-05-30 11:48
KIさんへ
こんにちは。 やはりミヤミスでした。グリッドで編集したカラムの座標と、対応するDatasetの座標の 指定の仕方を間違っていたため、Datasetに変更がされているにもかかわらず、 参照できていなかったということです。無事参照できました。 貴重な時間を割いていただいたにもかかわらず、ご迷惑をおかけしたことをお詫びします。 ただ関連するちょっとした技術情報を教えていただいたので勉強にはなりました。 大変申し訳ありませんでした。今後ともよろしくお願いいたします。 |
1