I have a series of textboxes and I wish for the first one that has no text to have the focus and have used the following.
Private Sub Set_Box_Focus()
Dim txt2 As TextBox
For L = 0 To MaxLetters - 1
txt2 = panGrid.Controls("txt" & L.ToString & CurrentTry.ToString)
If txt2.Text = "" Then
txt2.Focus()
Exit For
End If
Next
End Sub
Unfortunately this is not working. If the second one is empty the third one has the focus, if the third is enpty fifth has focus, if the fourth is empty seventh has focus. I have tried many things without success. The only one which works is inserting a msgbox.
Private Sub Set_Box_Focus()
Dim txt2 As TextBox
For L = 0 To MaxLetters - 1
txt2 = panGrid.Controls("txt" & L.ToString & CurrentTry.ToString)
If txt2.Text = "" Then
MsgBox(txt2.Name)
txt2.Focus()
Exit For
End If
Next
End Sub
This is obviously not useable but does show that the correct box is been chosen. I have come across using the msgbox to solve a problem before and have usually gone arround it. Any ideas?
CodePudding user response:
Assuming that those are the only TextBoxes
in that container and that the z-order is set appropriately, you can just do this:
panGrid.Controls.OfType(Of TextBox).
FirstOrDefault(Function(tb) tb.TextLength = 0)?.
Select()
If the z-order is not set appropriately, use the Document Outline window to change that.
Note that that code calls Select
rather than Focus
, just as the documentation clearly states.
CodePudding user response:
After 3 days it is driving me batty so I am posting the whole form so that it can be run and hopefuly someone can point out to me what an idiot I am!
Public Class Form1
Dim Letters() As String
Dim MaxLetters = 5
Dim MaxTries As Integer = 5
Dim CurrentTry As Integer = 1
Dim PanGrid As Panel
Dim btnCheck As Button
Dim Word As String = "PLANS"
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.Font = New Font("Microsoft Sans Serif,", 10, FontStyle.Bold)
Dim aPan As New Panel
With aPan
.Parent = Me
.Top = 40
.Left = 40
.Visible = True
End With
PanGrid = aPan
Dim aButton As New Button
With aButton
.Visible = True
.Text = "Check"
End With
btnCheck = aButton
AddHandler btnCheck.Click, AddressOf btnCheck_Click
End Sub
Public Sub Load_Grid()
Dim HW As Integer
Dim TabInx As Integer = 0
btnCheck.Parent = Me
PanGrid.Controls.Clear()
CurrentTry = 1
For T = 1 To MaxTries
For L = 1 To MaxLetters
Dim Txt As New TextBox
With Txt
.TextAlign = HorizontalAlignment.Center
.Font = New Font("Microsoft Sans Serif,", 20, FontStyle.Italic)
HW = .Height
.Width = HW
.Top = (T - 1) * HW
.Left = (L - 1) * HW
.MaxLength = 1
.Parent = PanGrid
.Text = ""
.Name = "txt" & L.ToString & T.ToString
.Visible = True
.TabIndex = TabInx
.Tag = False
TabInx = 1
.Enabled = (T = CurrentTry)
End With
AddHandler Txt.KeyPress, AddressOf TextBox_KeyPress
AddHandler Txt.TextChanged, AddressOf TextBox_TextChanged
Next
Next
With PanGrid
.Width = MaxLetters * HW
.Height = MaxTries * HW
End With
With btnCheck
.Height = HW
.Top = PanGrid.Top
.Left = PanGrid.Left PanGrid.Width
.Show()
End With
ReDim Letters(MaxLetters)
For i = 0 To MaxLetters - 1
Letters(i) = Word.Substring(i, 1)
Next
End Sub
Private Sub TextBox_TextChanged(sender As Object, e As EventArgs)
Dim S As String = sender.text
If S <> "" Then
SendKeys.Send("{TAB}")
End If
For L = 1 To MaxLetters
Dim txt As TextBox = PanGrid.Controls("txt" & L.ToString & CurrentTry.ToString)
txt.SelectionLength = 0
Next
End Sub
Private Sub TextBox_KeyPress(sender As Object, e As KeyPressEventArgs)
Dim KC As Integer = Asc(e.KeyChar)
If KC >= 97 And KC <= 122 Then
KC -= 32
ElseIf KC >= 65 And KC <= 90 Then
Else
KC = 0
If sender.text <> "" Then
KC = Asc(sender.text)
End If
End If
sender.Text = ""
e.KeyChar = Chr(KC)
End Sub
Private Sub btnCheck_Click(sender As Object, e As EventArgs)
'Value in every box
For L = 1 To MaxLetters
Dim Txt As TextBox = PanGrid.Controls("txt" & L.ToString & CurrentTry.ToString)
If Txt.Text = "" Then
Txt.Select()
Exit Sub
End If
Next
'Check if any letters match in correct order
Dim Cnt As Integer = 0
For L = 1 To MaxLetters
Dim Txt As TextBox = PanGrid.Controls("txt" & L.ToString & CurrentTry.ToString)
If Txt.Text = Letters(L - 1) Then
Txt.BackColor = Color.LightGreen
Letters(L - 1) = "-"
End If
If Letters(L - 1) = "-" Then Cnt = 1
Next
'If all letters have not been matched
If Cnt <> MaxLetters Then
'Check if any letters match in any order
For L = 1 To MaxLetters
Dim Txt As TextBox = PanGrid.Controls("txt" & L.ToString & CurrentTry.ToString)
For L2 = 1 To MaxLetters
If Txt.Text = Letters(L2 - 1) Then
If Txt.BackColor <> Color.LightGreen Then Txt.BackColor = Color.LightBlue
End If
Next
Next
CurrentTry = 1
For T = 1 To MaxTries
For L = 1 To MaxLetters
Dim Txt As TextBox = PanGrid.Controls("txt" & L.ToString & T.ToString)
With Txt
.Enabled = (T = CurrentTry)
If T = CurrentTry Then
Dim Txt2 As TextBox = PanGrid.Controls("txt" & L.ToString & (T - 1).ToString)
If Txt2.BackColor = Color.LightGreen Then
Txt.Text = Txt2.Text
Txt.BackColor = Txt2.BackColor
.Enabled = False
End If
End If
End With
Next
Next
If CurrentTry = MaxTries Then
btnCheck.Hide()
Else
Set_Box_Focus()
btnCheck.Top = (CurrentTry - 1) * btnCheck.Height PanGrid.Top
End If
Else
btnCheck.Hide()
End If
End Sub
Private Sub Set_Box_Focus()
Dim txt As TextBox
For L = 1 To MaxLetters
txt = PanGrid.Controls("txt" & L.ToString & CurrentTry.ToString)
If Not (txt.BackColor = Color.LightGreen) Then
'The correct textbox is chosen but the wrong one is selected
txt.Select()
Exit For
End If
Next
End Sub
End Class