我的设置
我有以下(伪)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
作为(可读写)组合框。城市名称的组合框具有以下属性:
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。
答案 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 ...