【发布时间】:2013-07-09 19:23:44
【问题描述】:
我有一个空白表单,其中添加了默认的ComboBox、TextBox(仅用于接收焦点)和Label。组合框有一个数据绑定设置到表单上的私有属性。
设置:
Private Sub FormLoad(sender As System.Object, e As System.EventArgs) _
Handles MyBase.Load
Dim data = {New With {.Display = "", .Value = ""},
New With {.Display = "A", .Value = "A"},
New With {.Display = "B", .Value = "B"},
New With {.Display = "C", .Value = "C"}}
ComboBox1.DataSource = data
ComboBox1.DisplayMember = "Display"
ComboBox1.ValueMember = "Value"
ComboBox1.DataBindings.Add("SelectedValue", someClass, "SomeProperty")
End Sub
其中 someClass 是下面SomeClass 类型的私有变量:
Public Class SomeClass
Private _someProperty As String = ""
Public Property SomeProperty() As String
Get
Return _someProperty
End Get
Set(ByVal value As String)
_someProperty = value
Form1.Label1.Text = String.Format("Some property = ""{0}""", value)
End Set
End Property
End Class
预期行为:
默认Binding.DataSourceUpdateMode 是更改将传播OnValidation。
如果我从ComboBox 中选择一个值,然后在TextBox 上单击它,则DataBinding 会将新值写入指定的属性,并且我的主窗体上的标签将被更新。
可能的错误:
问题出现是因为我们有一个业务规则,要求我们在做出选择时立即执行验证。为了触发验证,ComboBox 必须失去焦点,因此通过将以下代码添加到 SelectionChangeCommitted 事件,我们可以以编程方式强制验证
Private Sub ComboChanged(sender As System.Object, e As EventArgs) _
Handles ComboBox1.SelectionChangeCommitted
TextBox1.Focus()
End Sub
问题在于这会破坏第一次选择的数据绑定。组合框肯定失去了焦点,它肯定有一个新的SelectedValue,并且验证肯定已经触发,但是数据绑定没有将新值写入someClass 上的SomeProperty(在这个例子中,setter 永远不会触发和标签,不更新)。在随后的选择中,setter 将触发
如有必要,我将从ComboBox1.SelectionChangeCommitted 事件中手动编写数据绑定,但感觉这是额外的工作,因为我还需要在验证事件期间处理代码。
ComboBox1.DataBindings.Item("SelectedValue").WriteValue()
问题:
- 不应该以编程方式和手动失去焦点做同样的事情吗?
- 为什么这对后续选择有效,但对第一个选择无效?
- 这实际上是 WinForms 中的一些错误,还是我做错了什么?
更新:
感谢到目前为止的回答。我想我更多的是寻找解释而不是解决方法。为什么即使控件已验证,在验证时更新的绑定属性也不会更新。此外,为什么它不是第一次发生,而是适用于所有未来的事件?
【问题讨论】: