vb.net - 如何从另一个模块更改表单元素的属性

时间:2015-02-06 14:22:52

标签: vb.net

我正在尝试根据属性的新值从公共属性(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

1 个答案:

答案 0 :(得分:1)

此问题是由VB.NET实现创建的表单类的默认实例引起的。有关默认实例could be found herethis 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,这样,每个想要通知的表单都可以订阅该事件并在需要时接收信息。