处理按键事件时,我无法输入选择
问题描述:
好吧,我有一系列文本框只能接受1到49的数字值 - 每个文本框中都有一个唯一的数字。验证时,如果在其中一个框中有重复的号码,我希望将焦点设置为突出显示文本的违规文本框,以便我可以开始键入,并且选择将消失。问题(我认为)是在选择可以被删除之前,新的按键事件被添加到文本中。在一个解决方案谷歌搜索,我指着这个网站后,其最终与该代码张贴由罗伯特·巴恩斯处理按键事件时,我无法输入选择
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控件中看到过这种行为,也没有看到过需要这样的过程,但这是一个有趣的功能。在在意识到发生了什么的如果语句中发生的任何情况下,我想通了,我可以acheive我想要用一行代码:
If tb.SelectionStart < tb.TextLength AndAlso Not [Char].IsControl(e.KeyChar) Then
tb.SelectedText = ""
End If
这只是放弃的选择,使空间给新的输入,给人一种更传统的微软行为。在这种情况下,我不需要设置e.Handled,因为我将代码放置在KeyPress事件的开始处,允许在后续代码中处理按键,以便根据jimcilhinney进行一些更改... 我有(其中的工作,但有一点马虎)
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
事件,该事件在用户试图离开控件时发生。在这一点上,你可以检查输入是一个数字,并且它是唯一的。如果不是,请拨SelectAll
TextBox
并将e.Cancel
设置为True
以防止控制失控。
是的。这也解决了能够粘贴无效输入的问题,这当然不涉及按下任何按键。 –
确定有帮助,但我已经使用KeyPress将值限制为数字,Backspace和Delete以及限制输入数字的范围......你是说我应该(甚至可以)完成所有这些在验证中还是应该分离两个事件之间的逻辑? – halfacreSal
当用户试图离开控件时,会引发“验证”事件。它不会阻止无效输入,但它会阻止用户在控件包含无效输入时离开控件,因此无法使用输入。如果你想首先防止无效输入,那么'KeyPress'是一个选项,但这只是为了防止非法字符。超出范围的数字仍然是您应该使用“验证”的。 – jmcilhinney