-1

Hey all I am using some UIAutomation code that was written in C#. So I converted it into VB.net so that I could integrate it into my own program I am making.

The code that has the error is this line:

Private Sub LogMessage(message As String)
    Dispatcher.BeginInvoke(DispatcherPriority.Normal, New SetMessageCallback(AddressOf DisplayLogMessage), message)
End Sub

The error is on the Dispatcher.BeginInvoke stating Error 1 Reference to a non-shared member requires an object reference..

The code in C# looks like this:

private void LogMessage(string message)
{
    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new SetMessageCallback(DisplayLogMessage), message);
}

And has no errors and works just fine.

What am I missing from the VB.net version to make it work correctly?

The original C# code can be found HERE.

My converted C# to VB.net code looks like this:

Imports System.Threading
Imports Automation = System.Windows.Automation
Imports System.Windows.Automation
Imports System.Windows.Threading

Public Class Form1
    Public Delegate Sub SetMessageCallback(ByVal [_Msg] As String)

    Private Sub Automate()
        LogMessage("Getting RootElement...")
        Dim rootElement As AutomationElement = AutomationElement.RootElement
        If rootElement IsNot Nothing Then
            LogMessage("OK." + Environment.NewLine)

            Dim condition As Automation.Condition = New PropertyCondition(AutomationElement.NameProperty, "UI Automation Test Window")

            LogMessage("Searching for Test Window...")
            Dim appElement As AutomationElement = rootElement.FindFirst(TreeScope.Children, condition)

            If appElement IsNot Nothing Then
                LogMessage("OK " + Environment.NewLine)
                LogMessage("Searching for TextBox A control...")
                Dim txtElementA As AutomationElement = GetTextElement(appElement, "txtA")
                If txtElementA IsNot Nothing Then
                    LogMessage("OK " + Environment.NewLine)
                    LogMessage("Setting TextBox A value...")
                    Try
                        Dim valuePatternA As ValuePattern = TryCast(txtElementA.GetCurrentPattern(ValuePattern.Pattern), ValuePattern)
                        valuePatternA.SetValue("10")
                        LogMessage("OK " + Environment.NewLine)
                    Catch
                        WriteLogError()
                    End Try
                Else
                    WriteLogError()
                End If

                LogMessage("Searching for TextBox B control...")
                Dim txtElementB As AutomationElement = GetTextElement(appElement, "txtB")
                If txtElementA IsNot Nothing Then
                    LogMessage("OK " + Environment.NewLine)
                    LogMessage("Setting TextBox B value...")
                    Try
                        Dim valuePatternB As ValuePattern = TryCast(txtElementB.GetCurrentPattern(ValuePattern.Pattern), ValuePattern)
                        valuePatternB.SetValue("5")
                        LogMessage("OK " + Environment.NewLine)
                    Catch
                        WriteLogError()
                    End Try
                Else
                    WriteLogError()
                End If
            Else
                WriteLogError()
            End If
        End If
    End Sub

    Private Function GetTextElement(parentElement As AutomationElement, value As String) As AutomationElement
        Dim condition As Automation.Condition = New PropertyCondition(AutomationElement.AutomationIdProperty, value)
        Dim txtElement As AutomationElement = parentElement.FindFirst(TreeScope.Descendants, condition)
        Return txtElement
    End Function

    Private Sub DisplayLogMessage(message As String)
        TextBox1.Text += message
    End Sub

    Private Sub LogMessage(message As String)
        Me.Dispatcher.BeginInvoke(DispatcherPriority.Normal, New SetMessageCallback(AddressOf DisplayLogMessage), message)
    End Sub

    Private Sub WriteLogError()
        LogMessage("ERROR." + Environment.NewLine)
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim automateThread As New Thread(New ThreadStart(AddressOf Automate))
        automateThread.Start()
    End Sub
End Class
StealthRT
  • 10,108
  • 40
  • 183
  • 342
  • Use Dispatcher only in a WPF app. In Winforms you use Me.BeginInvoke() – Hans Passant Feb 20 '16 at 19:17
  • @HansPassant Seems to have an issue now with **DispatcherPriority.Normal** after changing it to Me.BeginInvoke. The error is **Error 1 Value of type 'System.Windows.Threading.DispatcherPriority' cannot be converted to 'System.Delegate'.** – StealthRT Feb 20 '16 at 19:28

2 Answers2

2

Found the correct way of doing it:

Private Sub LogMessage(message As String)
    Me.BeginInvoke(New SetMessageCallback(AddressOf DisplayLogMessage), message)
End Sub

Thanks goes to @HansPassant for the help.

StealthRT
  • 10,108
  • 40
  • 183
  • 342
1

Dispatcher can be static. I think you need Me.Dispatcher.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445