在绑定的组合框中设置空值时的奇怪行为
Strange behavior when setting null value in bound ComboBoxes
我准备了一个小项目来展示我的问题。它由两个具有父子关系的数据表组成。我使用 vb.net 2010 框架 4.0.
- 开始一个新的 WinForm 项目。
- 在 Form1 设计器上,拖动一个 BindingNavigator、一个 Button 和两个 ComboBoxes。
- 在后面的代码中,复制以下代码:
Public Class Form1
Private dsMain As DataSet
Private WithEvents bndSource As New BindingSource
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
dsMain = New DataSet
'Create tables
Dim dtContacts As New DataTable("Contacts")
Dim col As DataColumn = dtContacts.Columns.Add("IDContact", GetType(Integer))
col.AllowDBNull = False
col.AutoIncrement = True
col.Unique = True
dtContacts.Columns.Add("FullName")
col = dtContacts.Columns.Add("IDCountry", GetType(Integer))
col.AllowDBNull = True
dsMain.Tables.Add(dtContacts)
Dim dtCountries As New DataTable("Countries")
col = dtCountries.Columns.Add("IDCountry", GetType(Integer))
col.AllowDBNull = False
col.AutoIncrement = True
col.Unique = True
dtCountries.Columns.Add("A2ISO")
dtCountries.Columns.Add("CountryName")
dsMain.Tables.Add(dtCountries)
'Add relation
Dim rel As New DataRelation("rel", dtCountries.Columns("IDCountry"), dtContacts.Columns("IDCountry"))
dsMain.Relations.Add(rel)
'Populate parent table
dtCountries.Rows.Add(1, "AF", "Afghanistan")
dtCountries.Rows.Add(2, "AL", "Albania")
dtCountries.Rows.Add(3, "DZ", "Algeria")
'Populate child table
dtContacts.Rows.Add(1, "First Contact", 3)
dtContacts.Rows.Add(2, "Second Contact", 1)
'Set bindings
bndSource.DataSource = dtContacts.DefaultView
BindingNavigator1.BindingSource = bndSource
ComboBox1.DataSource = dtCountries
ComboBox1.DisplayMember = "A2ISO"
ComboBox1.ValueMember = "IDCountry"
ComboBox1.DataBindings.Add("SelectedValue", bndSource, "IDCountry")
ComboBox2.DataSource = dtCountries
ComboBox2.DisplayMember = "CountryName"
ComboBox2.ValueMember = "IDCountry"
ComboBox2.DataBindings.Add("SelectedValue", bndSource, "IDCountry")
dsMain.AcceptChanges()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ComboBox1.Text = Nothing 'Set IDCountry to DBNull, same as ComboBox1.SelectedIndex = -1
ComboBox2.Text = Nothing
End Sub
End Class
- 运行项目。
- 尝试来回导航,并更改组合框中的项目:一切正确。
- 现在在 Contacts 表中设置 IDCountry = Null,这是允许的。为此,请单击 Button1。
- 在 ComboBox1 中,如果您 select 与单击按钮之前的项目相同,您会发现行为不再正确:ComboBox2 不会随 ComboBox1 相应地更新,而是保持为空。
- 如果你 select 另一个项目,从现在开始一切都是正确的。
这是 .net 数据绑定中的错误吗?如果是这样,是否有任何解决方法?
提前致谢。
这是我找到的解决方法。我没有找到我观察到的行为的原因,但这段代码对我有用:
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
If ComboBox1.SelectedIndex < ComboBox2.Items.Count Then ComboBox2.SelectedIndex = ComboBox1.SelectedIndex
End Sub
Private Sub ComboBox2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox2.SelectedIndexChanged
If ComboBox2.SelectedIndex < ComboBox1.Items.Count Then ComboBox1.SelectedIndex = ComboBox2.SelectedIndex
End Sub
它只是让 ComboBox 选择的索引相等。
还是谢谢你。
我准备了一个小项目来展示我的问题。它由两个具有父子关系的数据表组成。我使用 vb.net 2010 框架 4.0.
- 开始一个新的 WinForm 项目。
- 在 Form1 设计器上,拖动一个 BindingNavigator、一个 Button 和两个 ComboBoxes。
- 在后面的代码中,复制以下代码:
Public Class Form1
Private dsMain As DataSet
Private WithEvents bndSource As New BindingSource
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
dsMain = New DataSet
'Create tables
Dim dtContacts As New DataTable("Contacts")
Dim col As DataColumn = dtContacts.Columns.Add("IDContact", GetType(Integer))
col.AllowDBNull = False
col.AutoIncrement = True
col.Unique = True
dtContacts.Columns.Add("FullName")
col = dtContacts.Columns.Add("IDCountry", GetType(Integer))
col.AllowDBNull = True
dsMain.Tables.Add(dtContacts)
Dim dtCountries As New DataTable("Countries")
col = dtCountries.Columns.Add("IDCountry", GetType(Integer))
col.AllowDBNull = False
col.AutoIncrement = True
col.Unique = True
dtCountries.Columns.Add("A2ISO")
dtCountries.Columns.Add("CountryName")
dsMain.Tables.Add(dtCountries)
'Add relation
Dim rel As New DataRelation("rel", dtCountries.Columns("IDCountry"), dtContacts.Columns("IDCountry"))
dsMain.Relations.Add(rel)
'Populate parent table
dtCountries.Rows.Add(1, "AF", "Afghanistan")
dtCountries.Rows.Add(2, "AL", "Albania")
dtCountries.Rows.Add(3, "DZ", "Algeria")
'Populate child table
dtContacts.Rows.Add(1, "First Contact", 3)
dtContacts.Rows.Add(2, "Second Contact", 1)
'Set bindings
bndSource.DataSource = dtContacts.DefaultView
BindingNavigator1.BindingSource = bndSource
ComboBox1.DataSource = dtCountries
ComboBox1.DisplayMember = "A2ISO"
ComboBox1.ValueMember = "IDCountry"
ComboBox1.DataBindings.Add("SelectedValue", bndSource, "IDCountry")
ComboBox2.DataSource = dtCountries
ComboBox2.DisplayMember = "CountryName"
ComboBox2.ValueMember = "IDCountry"
ComboBox2.DataBindings.Add("SelectedValue", bndSource, "IDCountry")
dsMain.AcceptChanges()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ComboBox1.Text = Nothing 'Set IDCountry to DBNull, same as ComboBox1.SelectedIndex = -1
ComboBox2.Text = Nothing
End Sub
End Class
- 运行项目。
- 尝试来回导航,并更改组合框中的项目:一切正确。
- 现在在 Contacts 表中设置 IDCountry = Null,这是允许的。为此,请单击 Button1。
- 在 ComboBox1 中,如果您 select 与单击按钮之前的项目相同,您会发现行为不再正确:ComboBox2 不会随 ComboBox1 相应地更新,而是保持为空。
- 如果你 select 另一个项目,从现在开始一切都是正确的。
这是 .net 数据绑定中的错误吗?如果是这样,是否有任何解决方法?
提前致谢。
这是我找到的解决方法。我没有找到我观察到的行为的原因,但这段代码对我有用:
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
If ComboBox1.SelectedIndex < ComboBox2.Items.Count Then ComboBox2.SelectedIndex = ComboBox1.SelectedIndex
End Sub
Private Sub ComboBox2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox2.SelectedIndexChanged
If ComboBox2.SelectedIndex < ComboBox1.Items.Count Then ComboBox1.SelectedIndex = ComboBox2.SelectedIndex
End Sub
它只是让 ComboBox 选择的索引相等。
还是谢谢你。