我在文本框中输入随机字母时遇到问题。这是代码:
Imports Microsoft.VisualBasic
Imports System.Timers
Public Class Form1
Dim SlovaTimer As Timer
Dim AbecedaArray() As Char = {"A", "B", "C", "Č", "Ć", "D", "Dž", "Đ", "E", "F", "G", "H" _
, "I", "J", "K", "L", "Lj", "M", "N", "Nj", "O", "P", "R" _
, "S", "Š", "T", "U", "V", "Z", "Ž"}
Dim counter As Integer = 0
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
SlovaTimer = New Timer(200)
AddHandler SlovaTimer.Elapsed, New ElapsedEventHandler(AddressOf Handler)
SlovaTimer.Enabled = True
Button1.Enabled = False
End Sub
Private Sub Handler(ByVal sender As Object, ByVal e As ElapsedEventArgs)
If counter = 11 Then
SlovaTimer.Stop()
Button2.Enabled = False
Else
Dim ctrl As Control
For Each ctrl In Me.Controls
If (ctrl.GetType() Is GetType(TextBox)) Then
Dim txt As TextBox = CType(ctrl, TextBox)
If txt.Tag = counter Then
Dim random As New Random
Dim randletter As Integer = random.Next(0, 29)
Dim letter As String
letter = AbecedaArray(randletter)
txt.Text = letter
End If
End If
Next
SlovaTimer.Start()
End If
这是错误:跨线程操作无效:控制'TextBox1'从其创建的线程以外的线程访问。任何想法?谢谢!
答案 0 :(得分:2)
您收到此异常是因为您尝试更改非UI线程的线程中的文本框文本。
在这种情况下,您可以将System.Timers.Timer
替换为System.Windows.Forms.Timer
作为评论中建议的Plutonix,这可能会解决问题。
但是,如果您将来遇到这些例外,您应该知道如何处理这些例外。
要在winforms中对UI控件进行跨线程调用,您需要使用Invoke
。
创建一个设置文本框文本的方法,以及该方法的委托:
Delegate Sub SetTextCallback(txt as TextBox, newString As String)
Private Sub SetText(txt as TextBox, newString As String)
' Calling from another thread? -> Use delegate
If txt.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf SetText)
' Execute delegate in the UI thread, pass args as an array
Me.Invoke(d, New Object() {txt, newString})
Else ' Same thread, assign string to the textbox
txt.Text = newString
End If
End Sub
现在,正如您所看到的,如果InvokeRequired
的属性textbox
返回True
,此方法实际上会调用自身。如果它返回False
,则表示您可以安全地设置文本框的Text
。