在vb.net中输入随机字母到文本框

时间:2015-05-27 12:35:11

标签: arrays vb.net

我在文本框中输入随机字母时遇到问题。这是代码:

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'从其创建的线程以外的线程访问。任何想法?谢谢!

1 个答案:

答案 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