
こんにちは.お世話になっております.
まず,質問を開いて頂いてありがとうございます.
Windows7 HomePremium 64bit,Microsoft Visual C# 2010 Express
という環境の下,趣味でWindowsフォームアプリケーションを作成しております.
本日は,DataGridViewへ関連付けたデータの更新について質問させていただきました.
問題としては,一度プログラム上で
dataGridView1.DataSource = ds;
dataGridView1.DataMember = ds.Tables[0].TableName;
※ dsはDataSetクラスのインスタンスです.
とデータを関連づけた後に,ds.Table[0]に対して逆シリアライズをしてデータを更新してもDataGridViewの内容が更新されない,というものです.
更新後にスウォッチで見るとDataGridViewのDataSourceの内容は更新されているにも関わらずデータは更新しません.
これについて解決策・打開案をご存知の方がいらっしゃいましたらご教授ください.
蛇足かもしれませんが,他の質問を調べている際「デザイナでDataSourceを設定しているとプログラム上でそれを更新できない」という原因を元に解決した質問がありましたが,当方はデザイナでは設定しておりません.
以上です.よろしくお願いいたします.
No.3ベストアンサー
- 回答日時:
正直な所、最初の回答に記載した後者の状況であって、
バインドし直せばよいのだろうなと思っていましたが、
バインド設定のクリアと再設定もしていたのですね。
試して見ましたが、なかなか腑に落ちない動作になりますね。
DataSet.Tables.Clear() ではなく DataSet.Reset() を行うようにしてみたところ、
DataGridView の内容は空になりました。
データソースをクリアしても DataSet.DefaultViewManager あたりが
何処かに保持されているのでしょうか。。よくわかりません。
DataGridView への DataTable のバインドは、
DataSet を利用して DataSource および DataMember プロパティを設定する以外に
DataSource に DataTable を直接指定する利用方法もありますが、
それを試して見たところ、1度目は上手くいったように見えますが、
その後 DataSource を何に変更しても表示が変わらないというおかしな状態になりました。
データバインドはバインドしたインスタンスの中身を更新することで
表示に反映という利用方法が多いかとは思いますが、
バインドするオブジェクト自体を切り替えるのも
結構普通の利用方法だと思うのでなにかやり方があるのかもしれませんが、
見つけられませんでした。
DataSetを作り直す以外の回避方法としては、
データの持ち方や保存データの仕様などによって
利用可能かはわかりませんが以下のような手もありそうです。
・DataTable.WriteXml() で保存したデータを DataTable.ReadXml() を使って
バインドしたDataTableインスタンスをそのままに中身を更新する。
ReadXml() 前にテーブルのスキーマ(列)が準備されている必要があり、
スキーマが変化する場合は利用できない。
型付きデータセットの場合はいいかも?
・BindingSourceを介する。
DataGridViewにBindingSourceをバインドし、
BindingSourceにデータセットをバインドする。
イメージとしては以下のような感じ。
private DataSet testDataSet = new DataSet();
private BindingSource dataBinder = new BindingSource();
private void init()
{
this.dataBinder.DataSource = this.testDataSet;
this.dataBinder.DataMember = this.testDataSet.Tables[0].TableName;
this.dataGridView1.DataSource = this.dataBinder;
}
private void load()
{
try
{
this.dataBinder.DataSource = null;
this.dataBinder.DataMember = null;
deserialize();
}
finally
{
this.dataBinder.DataSource = this.testDataSet;
this.dataBinder.DataMember = this.testDataSet.Tables[0].TableName;
}
}
○おまけ
BindingListが話に出ていますので少し触れますと、
これは自作のデータクラスなどのリストをバインドする際に結構便利です。
BindingList<>は普通のList<>などと同じように任意のデータクラスを要素として使えますが、
そのままDataSourceにバインドすれば、BindingList<>への要素の増減が
自動的に表示に反映されます。
ただし、ソートやフィルタを利用する場合は自分で実装する必要があり、
要素の数ではなく要素(データクラス)内のフィールド(プロパティ)変化をリアルタイムに反映したい場合は
データクラスが INotifyPropertyChanged を実装する必要があります。
そのあたりを必要としない読み取り専用データのリストを表示したい場合などは便利です。
またそのほかに、上でも少し触れている BindingSource はいろいろなデータソースと
コントロールの間を仲介することが出来ます。
たとえば変化の通知手段を保たない List<> とコントロールの間に挟み、
BindingSource に対してデータ操作を行うことで、
表示にもList<>にも更新を行う、といったような使い方もできます。
(外付けのラッパーのようなイメージ)
ご回答ありがとうございます.
BindingSourceをテストクラスで使ってみました!
まさにこの動作を求めていた!という感じで感激しております.
BindingList<>も少し触ってみましたが,まだまだ可能性がありそうでワクワクしますね!
BindingSourceとともにこれから色々触って勉強していこうと思います.
質問内容について,解決しましたのでこれで質問も締め切らせて頂きます.
ありがとうございました!
No.2
- 回答日時:
DataSourceを一度nullにしてDataSetを再バインドすると表示されます。
私は使用したことがありませんが、
DataSetではなくBindingListを使えばこのような手間はいらないようですね。
回答ありがとうございます.
No1の方のお礼欄にも書かせていただいたのですが,同じものを割り当てても更新されませんでした.
ただし,一旦DataSetのインスタンスをDispose()して再度インスタンス化→逆シリアライズして割り当てると更新が行われました.
回答の文面からは,そんなことをしなくても良さそうに思われるのですが,その点についてももし私の方法で間違いがありましたらご教授頂けると幸いです.
BindingListについても調べてみます.
ありがとうございました!
No.1
- 回答日時:
ご質問の内容では、具体的にどういうコードを書いて
データソースを更新しているか書かれて居ませんので、
コードの書き方が悪いんじゃないでしょうか?
というぐらいしかアドバイス出来ることはありませんが。。。
実際の状況が不明なので書くだけ無駄になるかもしれませんが、
一応予想をしてもう少し言うとすれば、
DataGridViewがデータソースの更新を表示に反映できるのは、
ただデータバインドをしているからではなく、
データソースを更新した時、データソース自身が通知を行い、
DataGridViewはそれを受けてデータの再読み出し・再表示を行うからです。
データソースの更新通知が無効化されていればリアルタイムでの更新は行われなくなります。
(BeginLoadData()してEndLoadData()をしていない、など)
あるいは、データバインドで参照するデータソースは、
DataSource や DataMemberを設定した時点のデータを参照するため、
あとから同じテーブル名で別のインスタンスを作って
データセット内のテーブルを入れ替えた場合などには、
DataGridViewは古いインスタンス側を参照しているため
データセット内のものを参照していない、ということにもなりえます。
この回答への補足
情報不足で申し訳ありません.
以下のようにコードを書きました.
<逆シリアライズ部分(データ管理するクラス内に定義した関数)>
public void desirialize()
{
DataTable dt = new DataTable(TABLE_NAME);
System.IO.StreamReader sr = null;
System.Xml.Serialization.XmlSerializer serializer =
new System.Xml.Serialization.XmlSerializer(dt.GetType());
try
{
this.Tables.Clear();
sr = new System.IO.StreamReader(FILENAME);
dt = (DataTable)serializer.Deserialize(sr);
this.Tables.Add(dt);
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (sr != null)
{
sr.Close();
}
}
}
というクラスをインスタンス化し,
<呼び出し部(上のクラスをインスタンス化したクラス内のボタンクリックイベント内)>
dataGridView1.DataMember = "";
dataGridView1.DataSource = null;
dst.desirialize();
dataGridView1.DataSource = ds;
dataGridView1.DataMember = ds.Tables[0].TableName;
以上です.よろしくお願いいたします.
補足の文章,コード部分の締めの言葉を忘れておりました.
失礼な文章になってしまい申し訳ありません.
DataGridViewがどのようなタイミングでデータの更新・表示を行うのかは知りませんでした.
ありがとうございます.
補足に書き忘れておりましたが,
DataSourceとDataMemberを一旦削除して,削除したものと同じものを割り当てても更新がされなかったのですが,一旦DataSetのインスタンスをDispose()して再度インスタンス化→逆シリアライズして割り当てると更新が行われました.
これは正規の方法なのでしょうか?
もっと正しい(上手い)やり方があればご教授いただければ幸いです.
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Windows 10 このWindowsUpdateの失敗メッセージは何を物語るか? 5 2023/07/17 11:49
- Excel(エクセル) Excelでのデータ管理 6 2022/12/24 09:33
- Windows 10 Windows Updateの更新ができない場合に初期化 3 2023/01/18 20:00
- Excel(エクセル) Application.Volatile利用(excel2003) 1 2023/02/06 10:11
- ノートパソコン .dllファイルがありませんと表示される 5 2023/04/30 03:03
- その他(データベース) 更新クエリをリンクデータベーステーブルに実行し実行時エラー3362固有インデックスに重複する値が含ま 1 2022/09/21 11:44
- iCloud iPhoneのメールの引き継ぎの仕方について 1 2022/03/30 15:10
- ドライブ・ストレージ 古い外付けHDDから新品外付けHDDへのデータ移行方法 (Mac) 2 2022/12/11 02:01
- その他(パソコン・周辺機器) Windows10のアップデートがうまく行きません。 バージョン1909から21H1にアップデートし 6 2022/06/18 03:00
- 引越し・部屋探し NHK契約につきまして。 2 2023/06/10 15:57
このQ&Aを見た人はこんなQ&Aも見ています
-
DataGridViewの内容をDBに反映する時
Visual Basic(VBA)
-
CloseとDisposeの違い
Visual Basic(VBA)
-
データグリッドビューの一番最初の行に列を追加したい
Visual Basic(VBA)
-
-
4
フォームの再読み込み
Visual Basic(VBA)
-
5
DataGridViewのチェックボックスのON、OFFの判定方法
C言語・C++・C#
-
6
C# DataTableに最後に追加した行をDataGridView上で選択状態にする方法は?
C言語・C++・C#
-
7
DataGridViewの、選択されている行を取り出したい
Visual Basic(VBA)
-
8
データセットのレコード更新がしたい
Visual Basic(VBA)
-
9
FORMが開いているかどうかの確認方法
Visual Basic(VBA)
-
10
DataGridViewに空白がある場合はエラーにしたい
Visual Basic(VBA)
-
11
VB.NET2005 TextBox 高さ(Height) 変更
Visual Basic(VBA)
-
12
C# DataGridView のヘッダーセル中央揃え
C言語・C++・C#
-
13
VB.NETで DataRow()を利用して、値からコードを取得したい。
Visual Basic(VBA)
-
14
ピクチャーボックスの大きさに合わせて画像を表示
Visual Basic(VBA)
-
15
VB.NETでフォーム上にExcelのような表を表示する方法
Visual Basic(VBA)
-
16
VB2005EE:DataGridViewでチェックボックスを設けるには
Visual Basic(VBA)
-
17
VB.NET DataGridView 縦スクロールバーを常に表示
Visual Basic(VBA)
-
18
C# dataGridViewの値だけクリア
C言語・C++・C#
-
19
DataGridViewでyyyy/MM/dd
Visual Basic(VBA)
-
20
DataGridViewのカラムに自動で連番
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
DataGrdViewに関連付けたデータ...
-
DataGridViewで表示に制限をつ...
-
MSFlexGridのデータ表示位置の設定
-
VBAでページ番号、ページ最終行...
-
PDFメニューバーの右端にある(...
-
1台のサーバへの同一セグメント...
-
通貨表示??3桁区切りでカン...
-
wordの差し込み印刷について
-
VBによる可変長ファイルの読み書き
-
VB.NETで DataRow()を利用して...
-
VBA:小数点以下の数字を取得で...
-
エクセルvbaで、別シートの最下...
-
ExcelVBAを使って、値...
-
特定のセルが空白だったら、そ...
-
Excelのプルダウンで2列分の情...
-
文字列の後ろから必要分だけ削...
-
Accessのクエリで、replace関数...
-
【Excel VBA】指定行以降をクリ...
-
エクセルで、絶対値の平均を算...
-
VBA実行後に元のセルに戻りたい
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
DataGrdViewに関連付けたデータ...
-
【Excel VBA】先頭の「0」飛び...
-
Listviewのデータを上から順番...
-
VBAでページ番号、ページ最終行...
-
.NET SqlDataReader のレコー...
-
GASでスプレッドシートの一番上...
-
MSFlexGridのデータ表示位置の設定
-
DataGridViewで表示に制限をつ...
-
GridViewにバインドせずにデー...
-
ACCESSのVBAで[Split]について
-
コンパイルエラーSubまたは...
-
VBによる可変長ファイルの読み書き
-
VBA ピボットテーブル自動更新
-
VB6 → EXCEL にデーター出力
-
【ASP.NET MVC】一覧編集画面
-
通貨表示??3桁区切りでカン...
-
1台のサーバへの同一セグメント...
-
ASP C# データベースから1行取得
-
クラス内だけでhtmlデータをダ...
-
GoogleスプレッドシートからExc...
おすすめ情報