如何调用不同的UI控件?

时间:2015-01-26 04:43:01

标签: vb.net com invoke subform

    Private Sub FormStatusUpdate(Serverconnectionstatus as boolean) 
      If ServerConnectionStatus = True Then
         Try
            ' Enable Download/Upload/Sync Icon in Form
            For Each OpenedForms As Form In My.Application.OpenForms
                If Not TypeOf OpenedForms Is SplashScreen1 And Not TypeOf OpenedForms Is GroupOper Then
                    If OpenedForms.Text.EndsWith(")") Or OpenedForms.Text.EndsWith("*") Then
                        For Each ts_obj As ToolStrip In OpenedForms.Controls.OfType(Of ToolStrip)()
                            Dim btn_Updates1 = ts_obj.Items.Find("Download", True)
                            If btn_Updates1.Length > 0 Then
                                DirectCast(btn_Updates1(0), ToolStripItem).Enabled = True
                            End If
                            Dim btn_Updates2 = ts_obj.Items.Find("tsSync", True)
                            If btn_Updates2.Length > 0 Then
                                DirectCast(btn_Updates2(0), ToolStripItem).Enabled = True
                            End If
                            Dim btn_Updates3 = ts_obj.Items.Find("Upload", True)
                            If btn_Updates3.Length > 0 Then
                                DirectCast(btn_Updates3(0), ToolStripItem).Enabled = True
                            End If
                        Next
                    End If
                ElseIf TypeOf OpenedForms Is GroupOper Then
                    For Each gd_obj As Control In OpenedForms.Controls
                        If gd_obj.Name = "GoDownload" Or gd_obj.Name = "GoUpload" Then
                            gd_obj.Enabled = True
                        End If
                    Next
                End If
            Next....

问题:如何调用子表单中的UI控件?

我的主窗体在初始化期间打开了不同的子窗体。主窗体称为com对象。 com对象在另一个线程中响应。现在我需要通过com对象data_change事件(Ini_DataGroup_DataChanged)注意一些控件。我知道如何通知主窗体UI但无法在子窗体中找出这些控件。换句话说,我不知道如何在调用期间调用这些子表单控件。

这里是COM对象调用函数。

Private Sub Ini_DataGroup_DataChanged(subscriptionHandle As Object, requestHandle As Object, values() As Opc.Da.ItemValueResult) Handles Ini_DataGroup.DataChanged
    MsgBox("ERROR")
    If values(0).Quality.Equals(Opc.Da.Quality.Good) And values(0).Value.ToString = "1" Then
        OPCConnectionBool = True
    Else
        Try
            OPCConnectionBool = False
            subscriptionHandle = Nothing
            OPCNetServer.Disconnect()
            OPCNetServer = Nothing
            OfflineNotification.StartPosition = FormStartPosition.CenterScreen
            OfflineNotification.ShowDialog()
        Catch ex As Exception
            Exit Sub
        End Try
    End If

    Call FormStatusUpdate(OPCConnectionBool) ' Update Connection Status

End Sub

显然它抛出一个异常说:交叉线程和控件错误等。 因为COM是在不同的线程中创建的。那些ts_obj工具条不能被com调用。

我该如何解决这个问题?谢谢

2 个答案:

答案 0 :(得分:0)

我会像这样重写:

    For Each OpenedForms As Form In My.Application.OpenForms
        If Not TypeOf OpenedForms Is SplashScreen1 And Not TypeOf OpenedForms Is GroupOper Then
            If OpenedForms.Text.EndsWith(")") Or OpenedForms.Text.EndsWith("*") Then
                For Each ts_obj As ToolStrip In OpenedForms.Controls.OfType(Of ToolStrip)()
                    Dim btn_Updates1 = ts_obj.Items.Find("Download", True)
                    If btn_Updates1.Length > 0 Then
                        DirectCast(btn_Updates1(0), ToolStripItem).Enabled = True
                    End If
                Next
            End If
        End If
    Next

答案 1 :(得分:0)

您需要将UI代码编组到UI线程上。

这意味着在您的某个表单上调用Invoke()方法。

要从主窗体访问子窗体上的控件,我将通过子窗体上的属性公开这些控件:

Public ReadOnly Property SomeControl As TextBox
Get
  Return theTextBox
End Get
End Property