3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C#のBindingSourceを使ったフォームでComboBoxを使用する時は実行順番に気をつけないといけない

Posted at

この記事はC#(.NET Framework 4.6)とVisual Studio 2012を使用しております。

BindingSourceを使用したフォームで開いた最初のレコードの値が入れ替わってしまう現象で無駄にハマりましたのでメモを残します。

例えのフォーム

image

画像の通りです、全てのコントロールは何も設定せずD&Dしただけです。

名前
textBox1 TextBox
comboBox1 ComboBox
bindingSource1 BindingSource
bindingNavigator1 BindingNavigator

そのまんまですね。

間違った順番

kudamono.cs
private void Form1_Load(object sender, EventArgs e)
{
    DataSet1.MainTableRow new_row1 = (DataSet1.MainTableRow)this.DS.MainTable.NewRow();
    new_row1.id = 1;
    new_row1.cd = "B";
    this.DS.MainTable.Rows.Add(new_row1);
    new_row1 = (DataSet1.MainTableRow)this.DS.MainTable.NewRow();
    new_row1.id = 2;
    new_row1.cd = "A";
    this.DS.MainTable.Rows.Add(new_row1);
    DataSet1.MasterTableRow new_row2 = (DataSet1.MasterTableRow)this.DS.MasterTable.NewRow();
    new_row2.cd = "A";
    new_row2.name = "リンゴ";
    this.DS.MasterTable.Rows.Add(new_row2);
    new_row2 = (DataSet1.MasterTableRow)this.DS.MasterTable.NewRow();
    new_row2.cd = "B";
    new_row2.name = "バナナ";
    this.DS.MasterTable.Rows.Add(new_row2);

    this.bindingSource1.DataSource = this.DS.MainTable;
    this.textBox1.DataBindings.Add("text", this.bindingSource1, "id");
    this.comboBox1.DataBindings.Add("SelectedValue", this.bindingSource1, "cd");

    this.comboBox1.ValueMember = "cd";
    this.comboBox1.DisplayMember = "name";
    this.comboBox1.DataSource = this.DS.MasterTable;
}

結果
image

idが"1"のcdは"B"なのに"バナナ"ではなく"リンゴ"になってしまいました。

ハマった理由

最初、ComboBoxの設定をする時に以下の様に

kudamono.cs
this.comboBox1.DataSource = this.DS.MasterTable;
this.comboBox1.ValueMember = "cd";
this.comboBox1.DisplayMember = "name";

DataSourceから先にセットすると、SelectedIndexChangedイベントが発生するので

kudamono.cs
this.comboBox1.ValueMember = "cd";
this.comboBox1.DisplayMember = "name";
this.comboBox1.DataSource = this.DS.MasterTable;

としましょうと言うのを聞いたことがあり、この部分だけに執着してしまい無駄にハマり込んでしまいました。

正しい順番

kudamono.cs
private void Form1_Load(object sender, EventArgs e)
{
    DataSet1.MainTableRow new_row1 = (DataSet1.MainTableRow)this.DS.MainTable.NewRow();
    new_row1.id = 1;
    new_row1.cd = "B";
    this.DS.MainTable.Rows.Add(new_row1);
    new_row1 = (DataSet1.MainTableRow)this.DS.MainTable.NewRow();
    new_row1.id = 2;
    new_row1.cd = "A";
    this.DS.MainTable.Rows.Add(new_row1);
    DataSet1.MasterTableRow new_row2 = (DataSet1.MasterTableRow)this.DS.MasterTable.NewRow();
    new_row2.cd = "A";
    new_row2.name = "リンゴ";
    this.DS.MasterTable.Rows.Add(new_row2);
    new_row2 = (DataSet1.MasterTableRow)this.DS.MasterTable.NewRow();
    new_row2.cd = "B";
    new_row2.name = "バナナ";
    this.DS.MasterTable.Rows.Add(new_row2);

    this.comboBox1.ValueMember = "cd";
    this.comboBox1.DisplayMember = "name";
    this.comboBox1.DataSource = this.DS.MasterTable;

    this.bindingSource1.DataSource = this.DS.MainTable;
    this.textBox1.DataBindings.Add("text", this.bindingSource1, "id");
    this.comboBox1.DataBindings.Add("SelectedValue", this.bindingSource1, "cd");
}

結果
image

今度はちゃんと"バナナ"と表示してくれました!

…良く考えてみれば間違っていた時は

  1. Bindingする
  2. ComboBoxにBindingの値が入る
  3. ComboBoxを設定する
  4. イベントが発生して最初の項目が上書きされる

だから

  1. ComboBoxを設定する
  2. イベントが発生して最初の項目が入る
  3. Bindingする
  4. ComboBoxにBindingの値が上書きされる

と言う簡単な発想にたどり着けず無駄に過ごしていました。

おわりに

こんなヘッポコなのは私だけだと思いますが、鳥頭なのできっとまた忘れてハマってるかもしれません(汗

順番って大事ですよね。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?