【问题标题】:Proper Binding of a TextBox to an Object Property将文本框正确绑定到对象属性
【发布时间】:2018-07-02 18:49:57
【问题描述】:

我有一个带有属性的类,我需要将其绑定到 VB.NET 中的表单 TextBox。到目前为止,我的所有尝试都不会让 TextBox 从对象属性中实时更新。

我的课堂上有以下代码

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)

类中的对象在全局变量的模块中声明

Public CurrentServoFormServoManager As RobotModel2.Servo = New RobotModel2.Servo

对象/类工作正常,我可以从它的属性中写入和读取数据,没问题。如果我用它附加/创建一个 BindingList 并将其设置为 DataGridView 的数据源,则 DataGridView 中的单元格会正确更新。我似乎无法让它与文本框一起使用。我看不出我可能会错过什么。谢谢。

编辑 - 更多信息:

经过进一步研究,我发现了一篇类似的帖子,其中提到在属性为 null 时绑定到类的属性会导致它不起作用。您必须在绑定之前有数据。

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

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

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

所以...我仍然没有解决如何将 TextBoxes 绑定到可以预设并保留在适当位置的类对象的属性的解决方案。

【问题讨论】:

  • CurrentServoFormServoManager 到底是什么?
  • 你使用的是什么 UI 框架?
  • 我在 vb.net 中构建 Windows 窗体。 CurrentServoFormServoManager 只是 Servo 类的一个实例。哈哈。当我在研发期间尝试不同的事情时,我会使用长名称。
  • 我认为您的代码没有任何问题。您可能无意中用另一个文本框在设计器中隐藏了TextBoxCurrServoID。尝试将 TextBoxCurrServoID.BringToFront() 添加到您的 Form_Load 处理程序代码中。

标签: vb.net data-binding textbox inotifypropertychanged


【解决方案1】:

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

例如容器类:

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'

【讨论】:

  • 这可能不是您所说的最佳解决方案,但感谢您提出建议,因为它有效。容器对我来说是新的,所以我还了解了一个新工具。似乎 Visual Basic 或表单不喜欢尝试从传入的串行数据包创建的线程进行更新。当您使用对象集合和 GridView 时,BindingList 可以解决这个问题,但在许多情况下这不起作用。就像在这个场景中一样。不知何故,添加容器层使表单快乐并更新。谢谢。
  • 我认为您的原始代码中发生的情况是,当您第一次绑定时,它绑定到实际对象,而不是变量名。所以当你改变了变量名所指向的对象时,绑定仍然坚持原来的对象,而不是新的。
  • 这是有道理的,但目前,我不会更改对象。我设置了在运行时创建对象的代码,我所做的只是更新属性中的数据。当我通过按钮的代码执行此操作时,它可以工作。当我通过从入站串行数据包调用的线程安全函数执行此操作时,TextBoxes 根本不会更新。但它们与您的容器解决方案有关。
  • 哦,好吧,只要它有效,对吧? :-) 很高兴我能帮上忙。
  • 没错,哈哈。非常感谢!让我摆脱了一个讨厌的错误!
猜你喜欢
  • 2018-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-10
  • 2017-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多