トップ回答者
データバインディングについて

質問
-
データバインディング初心者です。
現在、顧客IDと顧客名称を編集するテキストボックスを2つ配置したテストプログラムを
作成しています。
1.フォーム起動時にWEBサービスからDataSetを取得。
2.バインディグ設定
3.顧客名入力
4.ボタンクリックでWEBサービスに接続し、入力内容をDBへADD
5.顧客IDをセットしたDataSetをWEBサービスから戻り値として受け取り。
(6.受け取ったID列が顧客IDテキストボックスに表示されない)DataSet ds = new DataSet(); int id = 0; private void Form1_Load(object sender, EventArgs e) { // XMLWebサービスからDataSetを読み込む ds = svc.getDataSet(id); ds.AcceptChanges(); if (id == 0) { ds.Tables["sample"].Rows.Add(); } // DataTableの名前は"sample" this.textBox1.DataBindings.Add(new Binding("text", ds, "sample.id", true, DataSourceUpdateMode.OnPropertyChanged, "")); this.textBox2.DataBindings.Add(new Binding("text", ds, "sample.name", true, DataSourceUpdateMode.OnPropertyChanged, "")); } private void button1_Click(object sender, EventArgs e) { if (id == 0) ds.Tables["sample"].Rows[0]["id"] = 0; ds.Tables["sample"].Rows[0].EndEdit(); //ここで顧客IDに 0 が表示される //XMLWebサービスでデータベースへADD->成功してます //ID列に値がセットされた、DataTable名sampleを含むDataSetを取得 ds = svc.CommitDataBase(ds); //ここで顧客IDの表示が変更されると思っています。 id = int.Parse(ds.Tables["sample"].Rows[0]["id"].ToString()); Console.WriteLine(id); //ID値が正しく出力 }
DBへの追加および、そのレコードのDataSetの取得は出来ていますが、顧客IDテキストボックスの
値が 0 のままです。基本的なことが理解出来ていないためだと思いますが、DataTableの列が変更されれば
テキストボックスの値も変更されるのがバインディグというものではないのでしょうか。よろしくお願いします。
VS 2010
回答
-
この場合ですと、ReadValueメソッドを使う必要があります。
this.texBox1.DataBindings("Text").ReadValue();
もし、バインディング先でソースの変更を監視することになったら大変なことになります(一定間隔でソースの全ての値を自分が持っている値と比較しなければならなくなるでしょう)。それよりもソースから変更されたという通知(INotityPropertyChangedを実装)を受け取って自分(Bindingオブジェクト)で再取得するか、外部から再取得するメソッド(ReadValue)を実行してもらう方が現実的です。
なお、UIを通して行った操作に関しては、UIが裏で適切な処理をしてくれていますので、あたかもソースの変更が自動的に反映されるように見えているだけです。
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/- 回答としてマーク 山本春海 2011年3月31日 8:35
-
何個の DataSet のインスタンスがあって、コントロールとバインディングされているのが何なのかを確認するとよいかと思います。
textbox1, textbox2 にバインディングされているのは、Form1_Load イベントで取得した DataSet ですので、Form1 のローカルメンバである ds を書き換えても、バインディングが見ている DataSet は Form1_Load イベントで取得したもののままです。
対応としては、
- データセットを取得するのではなく、最初に作成したデータセットを更新するようにする
- データセットをバインディングしないで、データセットを保持するオブジェクト(フォーム自身とか)をバインディング対象にする
などなどがあります。
- 回答としてマーク 山本春海 2011年3月31日 8:35
すべての返信
-
この場合ですと、ReadValueメソッドを使う必要があります。
this.texBox1.DataBindings("Text").ReadValue();
もし、バインディング先でソースの変更を監視することになったら大変なことになります(一定間隔でソースの全ての値を自分が持っている値と比較しなければならなくなるでしょう)。それよりもソースから変更されたという通知(INotityPropertyChangedを実装)を受け取って自分(Bindingオブジェクト)で再取得するか、外部から再取得するメソッド(ReadValue)を実行してもらう方が現実的です。
なお、UIを通して行った操作に関しては、UIが裏で適切な処理をしてくれていますので、あたかもソースの変更が自動的に反映されるように見えているだけです。
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/- 回答としてマーク 山本春海 2011年3月31日 8:35
-
trapemiya様
ありがとうございます。
private void button1_Click(object sender, EventArgs e) { if (id == 0) ds.Tables["sample"].Rows[0]["id"] = 0; ds.Tables["sample"].Rows[0].EndEdit(); ds= svc.CommitDataBase(ds); this.textBox1.DataBindings["text"].ReadValue(); id = int.Parse(ds.Tables["sample"].Rows[0]["id"].ToString()); }
状況が変わらないのですがReadValueの記述場所は間違いありませんでしょうか。
よろしくお願いします。
-
何個の DataSet のインスタンスがあって、コントロールとバインディングされているのが何なのかを確認するとよいかと思います。
textbox1, textbox2 にバインディングされているのは、Form1_Load イベントで取得した DataSet ですので、Form1 のローカルメンバである ds を書き換えても、バインディングが見ている DataSet は Form1_Load イベントで取得したもののままです。
対応としては、
- データセットを取得するのではなく、最初に作成したデータセットを更新するようにする
- データセットをバインディングしないで、データセットを保持するオブジェクト(フォーム自身とか)をバインディング対象にする
などなどがあります。
- 回答としてマーク 山本春海 2011年3月31日 8:35
-
K.Takaoka様、trapemiya様ありがとうございます。
データセットを取得し、最初に作成したデータセットを更新するように変更した結果、前進しました。
private void button1_Click(object sender, EventArgs e) { if (id == 0) ds.Tables["sample"].Rows[0]["id"] = 0; DataSet _ds = new DataSet(); _ds= svc.CommitDataBase(ds);//DataSetを取得し、 this.ds.Tables["sample"].Rows[0]["id"] = _ds.Tables["sample"].Rows[0]["id"];//最初に作成したDataSet(DataTableの内容)を更新 this.textBox1.DataBindings["text"].ReadValue();//IDテキストボックスが変わりました。 id = int.Parse(ds.Tables["sample"].Rows[0]["id"].ToString()); }
この方法でよいのかどうか分かりませんが、先に進むことができました。
ありがとうございました。
-
クリックイベントを下記のとおり記述し、データベースへのADD、Updateが正常に行われました。
private void button1_Click(object sender, EventArgs e) { if (id == 0) ds.Tables["sample"].Rows[0]["id"] = 0; this.ds.Tables["sample"].Rows[0].EndEdit(); DataSet _ds = new DataSet(); _ds= svc.CommitDataBase(ds); this.ds.Tables["sample"].Rows[0]["id"] = _ds.Tables["sample"].Rows[0]["id"]; this.ds.Tables["sample"].Rows[0]["name"] = _ds.Tables["sample"].Rows[0]["name"]; this.textBox1.DataBindings["text"].ReadValue(); this.textBox2.DataBindings["text"].ReadValue(); this.ds.Tables["sample"].AcceptChanges(); this.id = int.Parse(ds.Tables["sample"].Rows[0]["id"].ToString()); }
ご教示ありがとうございました。