Quantcast
Channel: VBForums - Visual Basic .NET
Viewing all articles
Browse latest Browse all 27513

VS 2010 Change textbox/label properties from separate thread from another class.

$
0
0
Hello everyone,

I've been crunching this issue through my brain for a day or so now. For simplicity, I took the problem out into a separate project to try to isolate the bug.
I have two forms, Output and Input. Output is the main form and contains two textboxes and a button. Clicking the button opens the second modal form, Input. On this form there exists several buttons and two textboxes. The buttons are labeled Start, End, and Toggle. The Start button begins a background worker that constantly looks at the state of a boolean variable, Toggle, that is controlled by, you guess it, the toggle button. The End button simply kills the thread. The purpose is to be able to switch the text and colors of the two textboxes on the OUTPUT form by clicking the toggle button on the INPUT form. For whatever reason, I cannot get them to change. The two textboxes on the INPUT form are simply there for my own sanity; to know that the delegates I have written actually work, but again, the two textboxes on the OUTPUT form wont change.

Here is the code from both forms:

Output form
Code:

Public Class OutputFrm

    Public Delegate Sub SetTextBoxText_Delegate(ByVal [TextBox] As TextBox, ByVal [text] As String)
    Public Delegate Sub SetTextboxColor_Delegate(ByVal [TextBox] As TextBox, ByVal [color] As Drawing.Color)

    Public Sub SetTextBoxColor_ThreadSafe(ByVal [TextBox] As TextBox, ByVal [color] As Drawing.Color)
        If [TextBox].InvokeRequired Then
            Dim Mydelegate As New SetTextboxColor_Delegate(AddressOf SetTextBoxColor_ThreadSafe)
            Me.Invoke(Mydelegate, New Object() {[TextBox], [color]})
        Else
            [TextBox].BackColor = [color]
        End If
    End Sub
    ' Delagate subs
    Public Sub SetTextBoxText_ThreadSafe(ByVal [TextBox] As TextBox, ByVal [text] As String)
        If [TextBox].InvokeRequired Then
            Dim Mydelegate As New SetTextBoxText_Delegate(AddressOf SetTextBoxText_ThreadSafe)
            Me.Invoke(Mydelegate, New Object() {[TextBox], [text]})
        Else
            [TextBox].Text = [text]
        End If
    End Sub

    Private Sub ModalBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ModalBtn.Click
        InputFrm.ShowDialog()
    End Sub

End Class

Input form
Code:

Public Class InputFrm

    Dim Toggle As Boolean = False
    Public Delegate Sub SetTextBoxText_Delegate(ByVal [TextBox] As TextBox, ByVal [text] As String)
    Public Delegate Sub SetTextboxColor_Delegate(ByVal [TextBox] As TextBox, ByVal [color] As Drawing.Color)

    Public Sub SetTextBoxColor_ThreadSafe(ByVal [TextBox] As TextBox, ByVal [color] As Drawing.Color)
        If [TextBox].InvokeRequired Then
            Dim Mydelegate As New SetTextboxColor_Delegate(AddressOf SetTextBoxColor_ThreadSafe)
            Me.Invoke(Mydelegate, New Object() {[TextBox], [color]})
        Else
            [TextBox].BackColor = [color]
        End If
    End Sub
    ' Delagate subs
    Public Sub SetTextBoxText_ThreadSafe(ByVal [TextBox] As TextBox, ByVal [text] As String)
        If [TextBox].InvokeRequired Then
            Dim Mydelegate As New SetTextBoxText_Delegate(AddressOf SetTextBoxText_ThreadSafe)
            Me.Invoke(Mydelegate, New Object() {[TextBox], [text]})
        Else
            [TextBox].Text = [text]
        End If
    End Sub

    Private Sub StartBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StartBtn.Click
        TestWorker.RunWorkerAsync()
    End Sub

    Private Sub StopBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles StopBtn.Click
        TestWorker.CancelAsync()
    End Sub

    Public Sub TestWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles TestWorker.DoWork
        Do
            If Toggle Then
                'These are the ones I'm actually trying to toggle
                OutputFrm.SetTextBoxText_ThreadSafe(OutputFrm.TB1, "I'm an apple!")
                OutputFrm.SetTextBoxColor_ThreadSafe(OutputFrm.TB1, Color.Firebrick)
                OutputFrm.SetTextBoxText_ThreadSafe(OutputFrm.TB2, "I'm a banana")
                OutputFrm.SetTextBoxColor_ThreadSafe(OutputFrm.TB2, Color.LimeGreen)
                'These are just for my own sanity
                SetTextBoxText_ThreadSafe(TB1, "I'm an apple!")
                SetTextBoxColor_ThreadSafe(TB1, Color.Firebrick)
                SetTextBoxText_ThreadSafe(TB2, "I'm a banana")
                SetTextBoxColor_ThreadSafe(TB2, Color.LimeGreen)
            Else
                'These are the ones I'm actually trying to toggle
                OutputFrm.SetTextBoxText_ThreadSafe(OutputFrm.TB2, "I'm an apple!")
                OutputFrm.SetTextBoxColor_ThreadSafe(OutputFrm.TB2, Color.Firebrick)
                OutputFrm.SetTextBoxText_ThreadSafe(OutputFrm.TB1, "I'm a banana")
                OutputFrm.SetTextBoxColor_ThreadSafe(OutputFrm.TB1, Color.LimeGreen)
                'These are just for my own sanity
                SetTextBoxText_ThreadSafe(TB2, "I'm an apple!")
                SetTextBoxColor_ThreadSafe(TB2, Color.Firebrick)
                SetTextBoxText_ThreadSafe(TB1, "I'm a banana")
                SetTextBoxColor_ThreadSafe(TB1, Color.LimeGreen)
            End If
            If TestWorker.CancellationPending Then
                Exit Do
            End If
        Loop

    End Sub

    Private Sub ToggleBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToggleBtn.Click
        If Toggle Then
            Toggle = False
        Else
            Toggle = True
        End If
    End Sub

End Class

As you can see, I have written delegates to determine if Invoke is required. When I step through I have found that the delegate will return Textbox.InvokeRequired as False when it should be True. I read that this can be cause by the controls handle not having been created yet, and to use the check If Textbox.IsHandleCreated in the delegate, but I do not believe this is the problem.

If anyone can provide any insight, it would be much appreciated.

Thanks,

Wes

Viewing all articles
Browse latest Browse all 27513

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>