我发现并能够在 Windows 窗体中重现一种特殊行为,即更新数据绑定文本框中的文本,然后更改边框样式将覆盖新的文本值。
重现:创建一个新窗体,添加三个 TextBox 控件,并使用以下代码:
Public Class Form1
Private Class SampleObject
Public Property MyText As String = String.Empty
End Class
Private _sampleObject1 As New SampleObject With {.MyText = "Old Text 1"}
Private _sampleObject2 As New SampleObject With {.MyText = "Old Text 2"}
Private _sampleObject3 As New SampleObject With {.MyText = "Old Text 3"}
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
TextBox1.DataBindings.Add(New Binding("Text", _sampleObject1, "MyText", True, DataSourceUpdateMode.OnValidation, String.Empty))
TextBox2.DataBindings.Add(New Binding("Text", _sampleObject2, "MyText", True, DataSourceUpdateMode.OnValidation, String.Empty))
TextBox3.DataBindings.Add(New Binding("Text", _sampleObject3, "MyText", True, DataSourceUpdateMode.OnValidation, String.Empty))
TextBox1.Text = "New Text 1"
TextBox2.Text = "New Text 2"
TextBox3.Text = "New Text 3"
'Application.DoEvents() '<- won't fix this.
'TextBox2.Invalidate() '<- won't fix this.
'TextBox2.Update() '<- won't fix this.
'TextBox2.Refresh() '<- won't fix this.
TextBox1.BorderStyle = BorderStyle.Fixed3D
TextBox2.BorderStyle = BorderStyle.FixedSingle
TextBox3.BorderStyle = BorderStyle.None
End Sub
End Class
运行此应用程序将为您提供一个包含三个文本框的表单。第一个将显示新的文本值,因为它的边框样式没有改变。其他两个文本框将显示它们的旧值。
我做了以下观察:
- 在 Form1_Load 的开头将第一个文本框的 BorderStyle 更改为其他内容将导致它也显示原始值而不是新值。
- 如果未注释,注释掉的行都不能纠正问题。
- 将文本分配移到边框样式更改后确实可以解决此问题,但此示例是使用 Form 类继承的更复杂应用程序的简化版本。
- 注释掉数据绑定也可以纠正这个问题,但这不是一个可行的选择。
- 在表单上放置一个新文本框并将其设置为第一个获得焦点的控件不会改变观察到的行为。
- 设置文本值
_sampleObjectN.MyText
而不是TextBoxN.Text
反转行为,以便没有边框更改的文本框显示旧值,而其他两个显示新值。 - 将 DataSourceUpdateMode 更改为
DataSourceUpdateMode.OnPropertyChanged
将更正此问题,但也会更改绑定的行为。
明显的修复是更改文本分配,以便在更改 BorderStyle 或更改 DataSourceUpdateMode 后分配它,但我的问题是:为什么会首先发生这种情况?
更新:应同事的要求,我在表单中添加了一个按钮,并更改了它的Click
事件以设置控件的边框样式,注释掉Form_Load
. 当应用程序运行时,我在文本框中看到了新值,正如预期的那样,但是当我单击按钮时,文本框 2 和 3 上的边框发生了变化,并且它们的文本值恢复为旧值!