将 TextBox 正确绑定到对象 属性

Proper Binding of a TextBox to an Object Property

我有一个 class 和一个 属性,我需要绑定到 VB.NET 中的表单文本框。到目前为止 none 我的尝试将使 TextBox 从对象属性实时更新。

我的 class

中有以下代码
Public Class Servo

    Implements System.ComponentModel.INotifyPropertyChanged

    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

    Private _ServoID As Integer

    Property ServoID() As Integer

        Get
            Return _ServoID
        End Get

        Set(ByVal Value As Integer)

            _ServoID = Value
            Call LoadModelInfo()

            RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("ServoID"))

        End Set

    End Property


End Class

在表单加载事件中我有绑定代码

TextBoxCurrServoID.DataBindings.Add("Text", CurrentServoFormServoManager, "ServoID", False, DataSourceUpdateMode.OnPropertyChanged)

来自 class 的对象在模块中声明为全局变量

Public CurrentServoFormServoManager As RobotModel2.Servo = New RobotModel2.Servo

object/class 工作正常,我可以从它的属性写入和读取数据,没问题。如果我 attach/create 使用它的 BindingList 并将其设置为 DataGridView 的数据源,则 DataGridView 中的单元格会正确更新。我似乎无法让它与 TextBox 一起工作。我看不出我可能遗漏了什么。谢谢

编辑 - 更多信息:

经过进一步研究,我发现了一个类似的 post,其中提到绑定到 class 的 属性 而 属性 为 null 会导致它无法工作.在绑定之前你必须有数据。

我在表单上添加了一个按钮并将绑定代码移到那里,并在加载事件中将其注释掉。然后我加载表格。用数据填充 CurrentServoFormServoManager 对象,然后单击按钮将 TextBoxes 绑定到 CurrentServoFormServoManager 属性。那行得通。我可以以编程方式更改数据和 TextBoxes 更新。

问题是。我不能真正将其用作解决方案。对象 CurrentServoFormServoManager 在这个程序中不断被销毁和重建。一旦你让它 = nothing 或 = 到一个新的伺服对象,数据绑定就会中断并且必须重置。我不能这样做,因为该事件发生在表单控件之外。它是由在不同时间从串口传入的数据包触发的。 IE:为了等待串口包重新绑定数据,我不得不挂起表格。这就是我试图在代码中摆脱的解决方案。

我还尝试填充伺服对象,然后绑定文本框,然后只更新数据而不重建对象,并且可以从表单上的按钮更新,但是从串行数据包传入的线程安全数据不会更新文本框。数据在对象属性中正确更新,通过 BindingList 绑定的数据网格更新正常,但 TextBoxes 不会。

所以...关于如何将 TextBox 绑定到可以预设和保留的 class 对象的属性,我仍然没有解决方案。

可能不是最好的解决方案,但如果您正在创建和销毁 Servo 对象(即不断更改 CurrentServoFormServoManager 引用),那么您可能需要一个容器 class 来容纳Servo 引用并通过委托公开其属性,然后在引用或 属性 更改时引发事件。

例如容器 class:

Imports System.ComponentModel

Public Class ServoContainer
  Implements System.ComponentModel.INotifyPropertyChanged

  Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

  Private WithEvents _servo As Servo

  Sub New()
    _servo = New Servo
  End Sub

  Property Servo As Servo
    Get
      Return _servo
    End Get
    Set(value As Servo)
      _servo = value
      RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("ServoID"))
    End Set
  End Property

  Private Sub _servo_PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Handles _servo.PropertyChanged
    RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("ServoID"))
  End Sub

  Property ServoID As Integer
    Get
      Return _servo.ServoID
    End Get
    Set(value As Integer)
      _servo.ServoID = value
    End Set
  End Property
End Class

实例化容器:

Public CurrentServoContainer As ServoContainer = New ServoContainer

按如下方式替换您当前的文本框绑定:

TextBoxCurrServoID.DataBindings.Add("Text", CurrentServoContainer, "ServoID", False, DataSourceUpdateMode.OnPropertyChanged)

现在,以下两行都将更新文本框:

CurrentServoContainer.Servo.ServoID = 99

CurrentServoContainer.Servo = New Servo With {.ServoID = 98} 'replace with your actual constructor'