gpt4 book ai didi

vb.net - 组合框数据绑定(bind)错误 - 如果以编程方式失去焦点,则不会写入值

转载 作者:行者123 更新时间:2023-12-04 04:50:14 26 4
gpt4 key购买 nike

我有一个空白表格,我在其中添加了默认 ComboBox , TextBox (仅用于接收焦点)和 Label .组合框有一个数据绑定(bind)设置到表单上的私有(private)属性。

设置:

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 类型的私有(private)变量以下:

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 会将新值写入指定的属性,并且我的主窗体上的 Label 将被更新。

可能的错误:

问题出现是因为我们有一个业务规则,要求我们在做出选择时立即执行验证。为了触发验证,ComboBox 必须失去焦点,因此通过将以下代码添加到 SelectionChangeCommitted事件,我们可以以编程方式强制验证

Private Sub ComboChanged(sender As System.Object, e As EventArgs) _
Handles ComboBox1.SelectionChangeCommitted
TextBox1.Focus()
End Sub

问题是这会破坏第一次选择的数据绑定(bind)。组合框肯定失去了焦点,它肯定有一个新的 SelectedValue并且验证肯定已经触发,但是数据绑定(bind)没有将新值写入 SomePropertysomeClass (在此示例中,setter 永远不会触发,并且标签不会更新)。在随后的选择中,setter 将触发

如有必要,请从 ComboBox1.SelectionChangeCommitted事件,我将手动编写数据绑定(bind),但感觉这是额外的工作,因为我还需要在验证事件期间处理代码。

ComboBox1.DataBindings.Item("SelectedValue").WriteValue()

问题:
  • 不应该以编程方式和手动失去焦点做同样的事情吗?
  • 为什么这适用于后续选择,但不适用于第一个?
  • 这实际上是 WinForms 中的一些错误,还是我做错了什么?

  • 更新:

    感谢您到目前为止的答案。我想我更多的是寻找解释而不是解决方法。为什么即使控件已验证,在验证时更新的绑定(bind)属性也不会更新。此外,为什么它不是第一次发生,而是适用于所有 future 的事件?

    最佳答案

    我会以不同的方式进行设置。您真的不应该从 SomeClass 更改您的 UI。目的。它应该只存储数据:

    Public Class SomeClass

    Private _someProperty As String = ""

    Public Property SomeProperty() As String
    Get
    Return _someProperty
    End Get
    Set(ByVal value As String)
    _someProperty = value
    End Set
    End Property

    End Class

    然后,更改您的 FormLoad 并修复您的数据绑定(bind),以便所有内容都是数据绑定(bind)的:
    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"}}

    Label1.DataBindings.Add("Text", someClass, "SomeProperty");

    ComboBox1.DataSource = data
    ComboBox1.DisplayMember = "Display"
    ComboBox1.ValueMember = "Value"
    ComboBox1.DataBindings.Add("SelectedValue", someClass, "SomeProperty",
    false, DataSourceUpdateMode.OnPropertyChanged)
    End Sub

    注意上面我们绑定(bind)了 someClass到您的标签,以便在更改组合框时,标签将被更新。

    最后一点是设置 DataSourceUpdateMode在您的组合框中到 OnPropertyChanged,这将允许您摆脱该事件处理程序。

    更好的是,你应该有 SomeClass继承自 INotifyPropertyChanged因为您正在对其进行数据绑定(bind),并且您希望确保对 SomeClass 的更改将使其通知 UI。

    关于vb.net - 组合框数据绑定(bind)错误 - 如果以编程方式失去焦点,则不会写入值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17556487/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com