vb2012 textbox backcolor does't change using t

2019-02-21 00:23发布

I wrote very simple thread example.

  1. Make normal form1 and drop 1 textbox
  2. run thread work on form load
  3. thread change a textbox backcolor looks like switch on/off

But, it doesn't work.....

Can you tell me why doesn't work??

see my source.

=====================================================================

Imports System.Threading

Public Class Monitor
    Public wObj As Worker = New Worker()
    Public MyThread As Thread = New Thread(AddressOf wObj.DoWork)

    Public Sub ChangeTBColor(pOption As Integer)
        If pOption = 1 Then
            tb1.BackColor = Color.Aqua
        Else
            tb1.BackColor = Color.Red
        End If
    End Sub



    Private Sub Monitor_Load(sender As Object, e As EventArgs) Handles Me.Load

        MyThread.Start()

        Console.WriteLine("Running OrgThread..")

        Console.WriteLine("Stop running")

    End Sub

    Private Sub BtnThreadStop_Click(sender As Object, e As EventArgs) Handles BtnThreadStop.Click

        Me.wObj.RequestStop()
    End Sub

End Class


Public Class Worker
    Private LoopStop As Boolean = True
    Public Sub DoWork()
        Console.WriteLine("User Thread Start!")
        Dim iTemp As Integer = 0

        While (LoopStop)

            Monitor.ChangeTBColor(iTemp Mod 2)

            iTemp = iTemp + 1

            Thread.Sleep(500)

        End While

        Console.WriteLine("User Thread End.!")
    End Sub

    Public Sub RequestStop()
        LoopStop = False
    End Sub
End Class

1条回答
倾城 Initia
2楼-- · 2019-02-21 00:49

As already mentioned, your starting a new thread for your work, the issue is your trying to change the color for a control that need invoking. With this said, we need a delegate for when the control needs to be invoked... In my example, I used one class that handles this all and works great. Also please make sure to import System.ComponentModel because this is needed for the BackgroundWorker... I used the background worker as it takes all the heavy lifting off you would need...

Imports System.ComponentModel
Imports System.Threading

Public Class Monitor
Delegate Sub SetColor(ByVal clr As Integer) 'Your delegate..
Private WithEvents bw As New BackgroundWorker

Public Sub ChangeTBColor(pOption As Integer)
    If Me.tb1.InvokeRequired Then 'Invoke if required...
        Dim d As New SetColor(AddressOf ChangeTBColor) 'Your delegate...
        Me.Invoke(d, New Object() {pOption})
    Else
        If pOption = 1 Then
            tb1.BackColor = Color.Aqua
        Else
            tb1.BackColor = Color.Red
        End If
    End If


End Sub

Private Sub Monitor_Load(sender As Object, e As EventArgs) Handles Me.Load
    bw.WorkerSupportsCancellation = True
    Console.WriteLine("Running OrgThread..")
    bw.RunWorkerAsync()

End Sub

Private Sub bw_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bw.DoWork
    Dim iTemp As Integer = 0
    Dim LoopStop As Boolean = True
    Console.WriteLine("User Thread Start!")

    While (LoopStop)
        If Not (bw.CancellationPending) Then
            ChangeTBColor(iTemp Mod 2)
            iTemp = iTemp + 1
            Thread.Sleep(500)
        Else
            e.Cancel = True
            LoopStop = False
        End If
    End While

End Sub

Private Sub bw_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bw.RunWorkerCompleted
    Console.WriteLine("User Thread End.!")
End Sub

Private Sub BtnThreadStop_Click(sender As Object, e As EventArgs) Handles BtnThreadStop.Click
    If bw.IsBusy Then
        bw.CancelAsync()
    Else
        Console.WriteLine("Running OrgThread..")
        bw.RunWorkerAsync()
    End If
End Sub

End Class

Here's my screenshot of my test... This is tried and tested. Please be sure to vote if this helps you!

enter image description here

查看更多
登录 后发表回答