为什么需要手动更新绑定的组合框?

时间:2018-11-15 08:30:03

标签: vb.net winforms entity-framework-6

我的设置

我有以下(伪)EF类:

class Department {
    int ID,
    string Name
}

class DepartmentCustomer {
    int ID,
    int CustomerID,
    Customer Customer,
    string Information,
    int DepartmentID,
    Department Department
}

Class Customer {
    int ID,
    string Name,
    int? CityID,
    City City
}

Class City{
    int ID,
    string Name,
    string PostalCode
}

我有一个表单,其中有一个List(of DepartmentCustomer)的BindingSource和以下字段:

  • DepartmentCustomer.Information作为(读写)文本框
  • DepartmentCustomer.Customer.Name作为(只读)文本框
  • DepartmentCustomer.Customer.City作为(可读写)组合框。

CustomerForm

城市名称的组合框具有以下属性:

ComboBoxCity.DataSource = ListOfCities  ' = List(Of City)
ComboBoxCity.ValueMember = "Id"
ComboBoxCity.DisplayMember = "Name"
ComboBoxCity.DataBindings.Add(New Binding("SelectedItem", DepartmentCustomerBindingSource, "Customer.City", True, DataSourceUpdateMode.OnPropertyChanged))

我的问题

发生DepartmentCustomerBindingSource.CurrentItemChanged时,组合框未同步;它有时会更新为正确的值,但是当在BindingSource中进一步导航时,它会保持选中前一个项目

因此,我必须执行以下操作才能手动更新组合框

Private Sub DepartmentCustomerBindingSource_CurrentItemChanged(sender As Object, e As EventArgs) Handles DepartmentCustomerBindingSource.CurrentItemChanged
    If DepartmentCustomerBindingSource.Current.Contact.City Is Nothing then
        ComboBoxCity.SelectedIndex = -1
    Else
        ComboBoxCity.SelectedItem = DepartmentCustomerBindingSource.Current.Contact.City
    End if
End Sub

(为简单起见,我在上面的代码中省略了强制转换。同样,这些示例类可能对IRL没有意义)

编辑

即使上面的代码也无法满足我的要求。 例如:我有两个DepartmentCustomer实例,一个实例带有Contact.City,第二个实例没有Contact.City。表单在第一次打开时显示城市。当我导航至第二条记录时,组合框变为空,但是当我返回至第一条组合框时,组合框仍为空。更令人惊讶的是,第一条记录已更新为Contact.City = Nothing:'(

编辑2:我自己的首选解决方案

我已从组合框(ComboBoxCity.DataBindings.Add(New Binding("SelectedItem", DepartmentCustomerBindingSource, "Customer.City", True, DataSourceUpdateMode.OnPropertyChanged)))中删除了数据绑定,并添加了以下子项

Private Sub ComboBoxCity_SelectedValueChanged(sender As Object, e As EventArgs) Handles ComboBoxCity.SelectedValueChanged
    DepartmentCustomerBindingSource.Current.Contact.City = ComboBoxCity.SelectedItem
End Sub

这可行,但是由于我的表单中有很多组合框,我认为必须有一种“自动”方式来同步双向绑定组合框...

编辑3:我丢了毛巾

即使我上面的“解决方案”无法按预期工作;使用上述代码时,实例的Contact.City无法正确更新...

我的问题

为什么必须手动执行此操作?我想念什么吗?我认为通过设置DataBinding,只要绑定BindingSource处于导航状态,它就会更新SelectedItem。

3 个答案:

答案 0 :(得分:1)

ComboBox数据绑定到SelectedItem属性和空值(Nothing)源值似乎存在问题(错误?)。

从另一面来看,绑定到SelectedValue则没有此问题。因此,解决方案/解决方法是绑定到SelectedItem以更新数据源,并绑定到SelectedValue以更新控件:

ComboBoxCity.DataBindings.Add(New Binding("SelectedItem", DepartmentCustomerBindingSource, "Customer.City", True, DataSourceUpdateMode.OnPropertyChanged))    
ComboBoxCity.DataBindings.Add(New Binding("SelectedValue", DepartmentCustomerBindingSource, "Customer.City.ID", True, DataSourceUpdateMode.Never))

答案 1 :(得分:0)

  

大多数情况下,控件不更新是与未正确实现接口INotifyPropertyChanged和IBindingList相关的问题。 – Marco Guignard

这让我开始思考:我确实在使用以下内容填充DepartmentCustomerBindingSource

DepartmentCustomerBindingSource.DataSource = DBContext.DepartmentCustomer.Local.ToList

将其更改为

DepartmentCustomerBindingSource.DataSource = DBContext.DepartmentCustomer.Local.ToBindingList

有效:-/

但是,当将数据源设置为特定记录而不是(Binding)List时,如何使它工作?

DepartmentCustomerBindingSource.DataSource = DBContext.DepartmentCustomer.Local.First

答案 2 :(得分:0)

经过反复试验,我找到了以下解决方案:

考虑以下代码:

ComboBoxCity.DataSource = ListOfCities  ' = List(Of City)
ComboBoxCity.ValueMember = "Id"
ComboBoxCity.DisplayMember = "Name"
ComboBoxCity.DataBindings.Add(New Binding("SelectedItem", DepartmentCustomerBindingSource, "Customer.City", True, DataSourceUpdateMode.OnPropertyChanged))

让我着迷的是将ComboBoxCity.DataSource设置为实现IBindingList的类型,如下所示:

DBContext.Cities.Load
CitiesBindingSource.DataSource = DBContext.Cities.Local.ToBindingList
ComboBoxCity.DataSource = CitiesBindingSource

因此,绑定数据不是绑定数据(在这种情况下为DepartmentCustomerBindingSource),而是仅数据源必须实现IBindingSource ...

相关问题