简体   繁体   中英

Input random letter to textbox in vb.net

I have problem with inputting random letter in textbox. Here's code:

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

Here's error: Cross-thread operation not valid: Control 'TextBox1' accessed from a thread other than the thread it was created on. Any idea? Thanks!

You are getting this exception because you are trying to change the text of a Textbox in a thread that is not the UI thread.

In this case, you can replace the System.Timers.Timer with System.Windows.Forms.Timer as Plutonix suggested in his comment, and this will probably solve the problem.

However, you should know how to handle these exceptions if you come across them in the future.

To make a cross-thread call to a UI control in winforms you need to use Invoke . Create a method for setting the text of a textbox, and a delegate to that method:

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

Now, as you can see, this method actually invokes itself if the property InvokeRequired of the textbox returns True . if it returns False , it means that you can safely set the Text of the textbox.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM