好的,我有一系列文本框,它们只接受 1 到 49 之间的数值 - 每个文本框中都有一个唯一的数字。验证时,如果其中一个框中存在重复的数字,我希望将焦点设置到有问题的文本框,并突出显示其文本,这样我就可以开始输入,并且选择将会消失。问题(我认为)是在删除选择之前将新的按键事件添加到文本中。在 Google 搜索解决方案时,有人向我指出了该网站上的一篇文章,该文章最终提出了 Robert Barnes 发布的这段代码
Private Sub txtScreen_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtScreen.KeyPress
If txtScreen.SelectionStart < txtScreen.TextLength AndAlso Not [Char].IsControl(e.KeyChar) Then
Dim SaveSelectionStart As Integer = txtScreen.SelectionStart
Dim sb As New StringBuilder(txtScreen.Text)
sb(txtScreen.SelectionStart) = e.KeyChar
'Add the pressed key at the right position
txtScreen.Text = sb.ToString()
'SelectionStart is reset after setting the text, so restore it
'Advance to the next char
txtScreen.SelectionStart = SaveSelectionStart + 1
e.Handled = True
End If
End Sub
这可行,但允许您一次改写一个字符,而不是通过一次按键删除(替换)整个内容。我以前从未在 Windows 控件中见过这种行为,也没有看到需要这样的过程,但这是一个有趣的功能。无论如何,在意识到 If 语句中发生的情况后,我发现我可以用一行代码实现我想要的目标:
If tb.SelectionStart < tb.TextLength AndAlso Not [Char].IsControl(e.KeyChar) Then
tb.SelectedText = ""
End If
这只是放弃选择并为新输入腾出空间,从而提供更传统的 Microsoft 行为。在这种情况下,我不需要设置 e.Handled,因为我将代码放在 KeyPress 事件的开头,从而允许在后续代码中处理按键
所以根据 jmcilhinney 我做了一些修改...... 我所拥有的(有效但有点草率)
Private Sub txtPick_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtNum1.KeyPress
Dim tb As TextBox = CType(sender, TextBox)
If tb.SelectionStart < tb.TextLength AndAlso Not Char.IsControl(e.KeyChar) Then
tb.SelectedText = ""
End If
'exclude all keypresses that aren't digits
If Not Char.IsDigit(e.KeyChar) Then e.Handled = True
Dim num As Integer = Val(String.Concat(tb.Text, e.KeyChar))
'make sure keypress keeps number in range
If num > 49 Or num < 1 Then e.Handled = True
'allow backspace, delete
If e.KeyChar = vbBack Or e.KeyChar = ChrW(Keys.Delete) Then e.Handled = False
End Sub
现在我有:
Private Sub txtPick_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtNum1.KeyPress
Dim tb As TextBox = CType(sender, TextBox)
'exclude all keypresses that aren't digits
If Not Char.IsDigit(e.KeyChar) Then e.Handled = True
'allow backspace, delete
If e.KeyChar = vbBack Or e.KeyChar = ChrW(Keys.Delete) Then e.Handled = False
End Sub
Private Sub txtNum_Validating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles txtNum1.Validating
Dim tb As TextBox = CType(sender, TextBox)
Dim num As Integer = Val(tb.Text)
If IsNumeric(tb.Text) Then
Select Case Val(tb.Text)
Case Is < 1, Is > 49
e.Cancel = True
End Select
End If
End Sub
清理得很好,工作完美,谢谢 jmchilinney!
最佳答案
KeyPress
是错误的事件。您应该处理 Validating
事件,该事件在用户尝试离开控件时发生。此时,您可以检查输入是否是数字并且是唯一的。如果不是,您可以在 TextBox
上调用 SelectAll
并将 e.Cancel
设置为 True
以防止控件丢失重点。
关于.net - 处理按键事件时,我无法在选择内容上键入内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23485026/