Vb.net 为什么我需要手动更新绑定的组合框?
我的设置 我有以下(伪)EF类:Vb.net 为什么我需要手动更新绑定的组合框?,vb.net,winforms,entity-framework-6,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 I
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
}
我有一个带有BindingSource的表单,用于列表(部门客户)
和以下字段:
作为(读写)文本框部门客户信息
作为(只读)文本框DepartmentCustomer.Customer.Name
作为(读写)组合框DepartmentCustomer.Customer.City
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实例,一个有联系人.City,第二个没有联系人.City。当表单第一次打开时,它显示城市;当我导航到第二条记录时,组合框变为空,但当我返回到第一条组合框时,它保持为空;更令人惊讶的是,第一条记录已更新为Contact.City=Nothing:'(
编辑2:我自己的非首选解决方案
我已经从组合框中删除了数据绑定(ComboBoxCity.DataBindings.Add(新绑定(“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没有正确更新
我的问题
为什么我必须手动执行此操作;我是否遗漏了什么?我认为通过设置数据绑定,它将在导航绑定的BindingSource时更新SelectedItem
大多数情况下,当控件不更新时,这是一个与接口INotifyPropertyChanged和IBinding相关的问题列表未(正确)执行–Marco Guignard 这让我想到:我确实在使用下面的内容填充DepartmentCustomerBindingSource
DepartmentCustomerBindingSource.DataSource = DBContext.DepartmentCustomer.Local.ToList
当更改为
DepartmentCustomerBindingSource.DataSource = DBContext.DepartmentCustomer.Local.ToBindingList
它的工作原理是:-/
但是,当将数据源设置为特定记录而不是(绑定)列表时,如何使其工作
与
SelectedItem
属性和null(Nothing
)源值绑定的ComboBox
数据似乎存在问题(bug?)
从另一端绑定到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))
经过反复试验,我找到了以下解决方案: 考虑到以下准则:
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…大多数情况下,当控件不更新时,这是与INotifyPropertyChanged和IBinding接口相关的问题列表未(正确)执行。@MarcoGuignard谢谢!!!看到我下面的答案(以及我的附加问题)真的吗?那看起来很疯狂。可能有参考资料吗?参考资料?你一定是在开玩笑:)尝试和错误。将INotifyPropertyChanged的实现添加到DepartmentCustomer类中,方法是最好使用ForeignKey属性在组合的选定值之间进行链接box@MarcoGuignard我不知道为什么以及如何去做。每个想使用组合框更新EF POCO的人都必须实现这一点吗?在组合框上,将数据源设置为城市集合(如果不更新城市列表,列表就足够了),将DisplayMember设置为Name,ValueMember设置为ID。然后在组合框的SelectedValue和包含客户的BindingSource的CityID属性之间设置绑定。
DBContext.Cities.Load
CitiesBindingSource.DataSource = DBContext.Cities.Local.ToBindingList
ComboBoxCity.DataSource = CitiesBindingSource