我正在尝试根据属性的新值从公共属性(LogQry)的Set-procedure更改按钮的背景颜色(cmdLogQry)。
如果属性在包含按钮的表单中更改属性(在相同或甚至另一个按钮的Click方法中),则它有效。但是,如果从另一个模块更改属性(COM端口DataReceived事件的处理程序过程),则它不起作用。没有错误消息或任何内容 - LogQry可以更改其值,但按钮的颜色不会改变。
我做错了什么?
Public Class Handler
Private _logQry As Boolean = False
Public Property LogQry() As Boolean
Get
Return _logQry
End Get
Set(ByVal value As Boolean)
_logQry = value
If value Then
frmMain.cmdLogQry.BackColor = Color.Red
Else
frmMain.cmdLogQry.BackColor = Color.Blue
End If
End Set
End Property
Private Sub comPort_DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
...
LogQry = Not LogQry ' does NOT change color
...
End Sub
End Class
Public Class frmMain
Private comm As New Handler()
...
Private Sub cmdLogQry_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdLogQry.Click
comm.LogQry = Not comm.LogQry ' does change color
End Sub
...
End Class
答案 0 :(得分:1)
此问题是由VB.NET实现创建的表单类的默认实例引起的。有关默认实例could be found here和this answer from Hans Passant的更多内容 基本上,当您定义表单类时,VB.NET编译器会创建一个名称与该类名称相同的类的默认实例,但这会在面向对象的环境(如.NET)中产生许多误解。
要解决您的问题,您需要在Handler类中实现一个构造函数,该构造函数接收frmMain的实际实例,将其存储在类变量中,并在您想要修改实际显示的表单上的内容时使用该实例
Public Class Handler
Private _logQry As Boolean = False
Private _mainInstance As frmMain
Public Sub New(mainInstance as frmMain)
_mainInstance = mainInstance
End Sub
Public Property LogQry() As Boolean
Get
Return _logQry
End Get
Set(ByVal value As Boolean)
_logQry = value
If value Then
_mainInstance.cmdLogQry.BackColor = Color.Red
Else
_mainInstance.cmdLogQry.BackColor = Color.Blue
End If
End Set
End Property
....
End Class
现在,当您创建Handler实例时,将引用传递给当前的frmMain
Public Class frmMain
Private comm As Handler
...
Private Sub cmdLogQry_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdLogQry.Click
comm = new Handler(Me)
comm.LogQry = Not comm.LogQry ' does change color
End Sub
...
End Class
请记住,此解决方案也会产生问题。它将Handler类与你的frmMain结合在一起,两者现在是不可分割的。可能更好的方法是在Handler类中创建一个Event,这样,每个想要通知的表单都可以订阅该事件并在需要时接收信息。