绑定源的意外行为

时间:2013-06-01 20:10:16

标签: c# .net winforms bindingsource

我并不总是向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

我们还要说一个名为“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

表单上有两个组合框cmbCountrycmbCity,两者分别绑定到CountryCity类型的BindingSource,“DisplayMember”设置为“两个组合框的名称“和”ValueMember“设置为”ID“。 SelectedValue的{​​{1}}属性绑定到cmbCountry的{​​{1}}属性,CountryID的{​​{1}}属性绑定到citizenViewModelBindingSource同一绑定源的属性,因此组合框显示的值会根据在DGV中选择的项目而更改。

我正在处理SelectedValue cmbCity后面的CityID事件,因此当所选国家/地区发生变化时,CurrentChanged会显示所选国家/地区的城市。

countryBindingSource

问题如下:假设我的结果集有5行,其中2行具有相同的CountryID但不同的CityID,而其他3行具有所有不同的CountryID和CityID。当我选择具有相同CountryID的两个项目之一,然后选择具有相同CountryID的另一个项目时,具有城市的组合框将相应地更新。但是,如果我首先选择具有相同CountryID的这两个中的一个,然后选择具有不同CountryID的那一个并最终选择具有相同CountryID的另一行,则绑定源将神奇地分配与之前选择的具有相同CityID的CityID相同的CityID。 CountryID。混乱?我将用一个例子来解释(并省略不相关的字段)。

  

结果:
  1.姓名:John Doe;国家:美国;城市:西雅图
  2.姓名:约翰史密斯;国家:加拿大;城市:蒙特利尔
  3.姓名:迈克尔欧文;国家:英格兰;城市:利物浦
  名字:乔治布什;国家:美国;城市:华盛顿
  5.姓名:弗拉基米尔普京;国家:俄罗斯;城市:莫斯科

选择John Doe,组合框说美国和西雅图 选择乔治布什,组合框说美国和华盛顿 选择John Doe,组合框说美国和西雅图 选择乔治布什,组合框说美国和华盛顿。所以一切都还不错 选择迈克尔欧文,组合框说英格兰和利物浦 选择John Doe,组合框说美国和西雅图 现在看这个。选择乔治布什,组合框说美国和西雅图(不应该是美国和华盛顿)。绑定源改变了乔治布什的CityID!

我已经完成了关于这个问题的写作,但解决方案还没有出现在我的脑海中。为什么会发生这种情况以及如何避免这种行为?

修改

通过解除cmbCountry的“SelectedValue”绑定并修改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);
}

但这对我来说似乎是一个黑客,如果有人知道为什么会发生这种情况,我会保持这个问题的开放。

1 个答案:

答案 0 :(得分:0)

通过解除cmbCity的“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的属性,就像它一样。” - 格特阿诺德