いつも Stack Overflow に問題を投稿するわけではありませんが、投稿する場合は、通常、問題の投稿が完了する前に解決策を見つけます。:-) 真剣に、BindingSource の奇妙な動作が発生しています。論理的な説明が見つからず、あなたの助けが必要です。
NET 4 を使用し、EntityFramework 4 を介して SQL データベースを読み取り、BindingList に格納されている ViewModel のリストに結果を書き込みます。これは、BindingSource を介して DataGridView にバインドされます。DataGridView の下には、DataGridView と同じ BindingSource にバインドされたチェック ボックス、テキスト フィールド、コンボ ボックスなどのさまざまなフィールドがあります。そうすれば、DataGridView からアイテムを選択すると、それらのすべてのフィールドが現在選択されている DataGridView アイテムで更新されます。
データベースに次のように定義された 2 つのテーブルがあるとします。
Table name: Country
-------------------
ID: integer, PK
Name: nvarchar
Table name: City
----------------
ID: integer, PK
CountryID: integer, FK to Country
Name: nvarchar
次のように定義された「Citizen」というデータベースにテーブルがあるとしましょう。
Table name: Citizen
-------------------
ID: integer, PK
CityID: integer, FK to City
Name: nvarchar
... (and other irrelevant fields)
DataGridView はBindingList<CitizenViewModel>
、「CitizenViewModel」が次のように定義されている場所にバインドされます。
class CitizenViewModel
{
public int ID { get; set; }
public int CityID { get; set; }
public string Name { get; set; }
public int CountryID { get; set; }
public CitizenViewModel(Citizen c)
{
this.ID = c.ID;
this.CityID = c.CityID;
this.Name = c.Name;
this.CountryID = c.City.CountryID;
}
}
DGV の BindingSource に名前を付けましょうcitizenViewModelBindingSource
。
フォームには と の 2 つのコンボ ボックスがあり、どちらもとタイプの BindingSources にそれぞれバインドされてcmbCountry
おり、両方のコンボ ボックスで "DisplayMember" が "Name" に設定され、"ValueMember" が "ID" に設定されています。のプロパティは同じバインド元のプロパティにバインドされ、 のプロパティはプロパティにバインドされるため、DGV で選択されている項目に応じて、コンボ ボックスに表示される値が変化します。cmbCity
Country
City
SelectedValue
cmbCountry
CountryID
citizenViewModelBindingSource
SelectedValue
cmbCity
CityID
の後ろにあるCurrentChanged
イベントを扱っているので、選択した国を変更すると、その選択した国の都市が表示されます。countryBindingSource
cmbCountry
cmbCity
private void countryBindingSource_CurrentChanged(object sender, EventArgs e)
{
// Get the list of Cities that belong to the selected Country
cityBindingSource.DataSource = GetCities(((Country)countryBindingSource.Current).ID);
}
問題は次のとおりです。結果セットに 5 つの行があり、そのうち 2 つの CountryID は同じですが CityID が異なり、残りの 3 つの CountryID と CityID がすべて異なるとします。同じ CountryID を持つ 2 つの項目の 1 つを選択してから、同じ CountryID を持つもう 1 つの項目を選択すると、それに応じて都市のコンボ ボックスが更新されます。ただし、最初に同じ CountryID を持つこれら 2 つのうちの 1 つを選択し、次に異なる CountryID を持つそれらのいずれかを選択し、最終的に同じ CountryID を持つ他の行を選択すると、バインディング ソースは魔法のように同じ CityID を以前に選択した行と同じに割り当てます。国 ID。混乱しますか?例を挙げて説明します (不要なフィールドは省略します)。
結果:
1. 名前: John Doe; 国: 米国; 都市: シアトル
2. 名前: ジョン・スミス; 国: カナダ; 都市: モントリオール
3. 名前: マイケル・オーウェン。国: イングランド; 都市: リバプール
4. 名前: ジョージ・ブッシュ。国: 米国; 都市: ワシントン
5. 名前: ウラジミール・プーチン; 国: ロシア; 都市: モスクワ
John Doe を選択すると、コンボ ボックスには USA と Seattle と表示されます。
ジョージ ブッシュを選択すると、コンボ ボックスには USA と Washington と表示されます。
John Doe を選択すると、コンボ ボックスには USA と Seattle と表示されます。
ジョージ ブッシュを選択すると、コンボ ボックスには USA と Washington と表示されます。だから、まだ大丈夫です。
Michael Owen を選択します。コンボ ボックスには、イングランドとリバプールが表示されます。
John Doe を選択すると、コンボ ボックスには USA と Seattle と表示されます。
これを見てください。George Bush を選択すると、コンボ ボックスには USA と Seattle と表示されます (本来の USA と Washington ではありません)。バインディング ソースは、ジョージ ブッシュの CityID を変更しました!
問題について書き終えましたが、解決策が頭に浮かびません。これが発生する理由と、この動作を回避する方法を教えてください。
編集
「SelectedValue」のバインドを解除し、関数を次のようcmbCity
に変更することで問題を解決しました。countryBindingSource_CurrentChanged
private void countryBindingSource_CurrentChanged(object sender, EventArgs e)
{
if (citizenViewModelBindingSource.Current != null)
{
cityBindingSource.DataSource = GetCities(((Country)countryBindingSource.Current).ID);
// update the combo box manually
cmbCity.SelectedValue = ((CitizenViewModel)citizenViewModelBindingSource.Current).CityID;
}
}
しかし、これは私にはハッキングのように思えます。なぜこれが起こるのかについて誰かが手がかりを持っているなら、私はこの質問を開いたままにします.