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

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

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

# 例えのフォーム

![image](https://qiita-image-store.s3.amazonaws.com/0/89730/972dcafa-5a98-856d-70b5-4769e9fa68f9.png)

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

|名前|型|
|:-:|:-:|
|textBox1|TextBox|
|comboBox1|ComboBox|
|bindingSource1|BindingSource|
|bindingNavigator1|BindingNavigator|

そのまんまですね。

# 間違った順番

```csharp: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](https://qiita-image-store.s3.amazonaws.com/0/89730/829bc04c-ddcc-78f0-83b6-a4510f6f8c5d.png)

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

## ハマった理由
最初、ComboBoxの設定をする時に以下の様に

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

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

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

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

# 正しい順番

```csharp: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](https://qiita-image-store.s3.amazonaws.com/0/89730/719b060f-9991-6007-2b68-9b6f36198625.png)

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

…良く考えてみれば間違っていた時は
1. Bindingする
2. ComboBoxにBindingの値が入る
3. ComboBoxを設定する
4. イベントが発生して最初の項目が上書きされる

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

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

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

順番って大事ですよね。