2013-06-01 37 views
3

我並不總是向Stack Overflow發佈問題,但是當我這樣做時,我通常會在完成發佈問題之前找到解決方案。 :-)現在嚴重的是,我遇到了BindingSource的奇怪行爲,我找不到合理的解釋,我需要你的幫助。綁定源的意外行爲

使用NET 4,通過EntityFramework 4讀取SQL數據庫,將結果寫入存儲在BindingList中的ViewModel列表中,該列表隨後通過BindingSource綁定到DataGridView。在DataGridView下面有各種各樣的字段,例如與DataGridView綁定到相同BindingSource的複選框,文本字段和組合框。這樣,當您從DataGridView中選擇項目時,所有這些字段都將使用當前選定的DataGridView項目進行更新。

比方說,有一個數據庫中的兩個表被這樣定義:

Table name: Country 
------------------- 
ID: integer, PK 
Name: nvarchar 

Table name: City 
---------------- 
ID: integer, PK 
CountryID: integer, FK to Country 
Name: nvarchar 

我們還假設存在一個名爲「公民」數據庫中的表是這樣定義的:

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

有窗體上兩個組合框,cmbCountrycmbCity,二者結合到CountryCity類型的BindingSources分別與「DisplayMember」設置爲「名稱」和「ValueMember」設定爲「ID」爲兩個組合框。的cmbCountrySelectedValue屬性綁定到的citizenViewModelBindingSourceCountryID財產和cmbCitySelectedValue屬性綁定到相同的結合源的CityID屬性,所以在組合框根據DGV選擇的項目顯示的值的變化。

我處理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都不同CountryIDs和CityIDs。當我選擇具有相同CountryID的兩個項目中的一個,然後選擇具有相同CountryID的另一個項目時,帶有城市的組合框將相應更新。但是,如果我首先選擇具有相同CountryID的這兩個中的一個,然後選擇具有不同CountryID的其中一個,並最終選擇具有相同CountryID的另一行,則綁定源將奇蹟般地分配與先前選擇的行相同的CityID CountryID。混亂?我將用一個例子來解釋(並省略不相關的字段)。

結果:
1.名稱:John Doe;國家:美國;城市:西雅圖
2.名稱:約翰史密斯;國家:加拿大;城市:蒙特利爾
3.名稱:邁克爾歐文;國家:英格蘭;城市:利物浦
4.名稱:喬治布什;國家:美國;城市:華盛頓
5。姓名:弗拉基米爾普京;國家:俄羅斯;城市:莫斯科

選擇John Doe,組合框稱美國和西雅圖。
選擇喬治布什,組合框說美國和華盛頓。
選擇John Doe,組合框稱美國和西雅圖。
選擇喬治布什,組合框說美國和華盛頓。所以一切都還好。
選擇邁克爾歐文,組合框說英格蘭和利物浦。
選擇John Doe,組合框稱美國和西雅圖。
現在看這個。選擇喬治布什,組合框說美國和西雅圖(應該是美國和華盛頓)。綁定來源已經改變了George Bush的CityID!

我已經完成了關於這個問題的寫作,但解決方案並沒有出現在我的腦海。爲什麼會發生這種情況,以及如何避免這種行爲?

編輯

解決了解除綁定的cmbCity「的SelectedValue」和修改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; 
     } 
    } 

但是,這似乎是一個黑客給我,我將保持這個問題如果有人知道爲什麼會發生這種情況,請打開。

+0

在VB中,當值真的發生變化時,組合框中會出現「Changed Commited」。你是否嘗試過,如果用C#退出?數據庫正在更新或僅在UI上出錯?也許它按照名字[S] eatle和[W] ashington選擇第一個城市。 – Jaxedin

+0

@OwerFlov這僅僅是一個例子,這兩座城市被分類的事實是一個巧合。數據庫沒有更新,除了我發佈的代碼外,沒有其他代碼涉及這種情況。還有當我選擇從DGV –

+1

你介意你的移動解決方案的答案,將其標記爲在適當的時候接受了記錄與ItemChanged型觸發一個事件引發ListChanged?我認爲你不能做任何事情,除了遠離數據綁定,因爲在數據綁定時改變組合框的內容會修改綁定到Selectedvalue的屬性,就像它或不是。 –

回答

0

通過解除該問題,解除的「SelectedValue」並手動設置cmbCity.SelectedValue。通過修改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; 
     } 
    } 

「我想是因爲改變一個組合框的內容,而它的數據綁定修改綁定的SelectedValue財產,你不能做任何事情,但是從數據綁定搬走,喜歡還是不喜歡。「 - Gert Arnold