事件未在First KeyPress上触发

时间:2018-10-22 00:02:03

标签: vb.net

我正在尝试从文本框的keyPress事件中调用Sub,问题是直到第二个keyPress才调用Sub,那时,如果第三个keyPress是完成后,子程序将处理第二个keyPress,以此类推...这是图像;

Form KeyPress

这是我的代码;

Private nonNumberEntered As Boolean = False

Private Sub txtAmount_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtAmount.KeyPress
    'Only allowed characters
    Dim allowedChars As String = "0123456789."
    nonNumberEntered = False
    If Char.IsDigit(e.KeyChar) = False And Char.IsControl(e.KeyChar) = False Then
        If e.KeyChar <> ControlChars.Back Then
            If allowedChars.IndexOf(e.KeyChar) = -1 Then
                ' Invalid Character, notify clear and return
                MsgBox("Numbers only", MsgBoxStyle.Exclamation)
                txtAmount.Text = ""
                txtAmount.Focus()
                nonNumberEntered = True
            End If
        End If
    End If
    'If shift key was pressed, it's not a number.
    If Control.ModifierKeys = Keys.Shift Then
        nonNumberEntered = True
    End If
    'Call the function to create a text line out of the numbers
    'Regex to ensure the string contains numbers
    Dim re As New Text.RegularExpressions.Regex("\d")
    If re.IsMatch(txtAmount.Text) Then
        If nonNumberEntered = False Then
            Dim newNum = txtAmount.Text.Trim
            'If there are any leading weird . in the string
            newNum = newNum.TrimStart(".")
            Dim newStr As String
            'Build the array
            Dim newDec As String() = newNum.Split(New Char() {"."c})
            If newNum.Contains(".") Then
                newStr = NumberToText(newDec(0))
                lblResult.Text = newStr & " Dollars and " & newDec(1) & "/100 "
            Else
                newStr = NumberToText(newDec(0))
                lblResult.Text = newStr & " Dollars and 00/100 "
            End If

        End If
    End If
End Sub

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

正如@jmcilhinney在注释中提到的那样,您正在尝试在KeyPress事件处理程序中做太多事情。该处理程序仅应用于允许有效的按键操作和禁止无效的按键操作。只要进行有效的按键操作,都将允许其进行操作,然后将调用TextChanged事件处理程序。设置e.Handled = True将禁止按键,并且TextChanged事件不会被调用。

Private Sub txtAmount_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox2.KeyPress
    'Only allowed characters
    Dim allowedChars As String = "0123456789."

    If Char.IsDigit(e.KeyChar) = False And Char.IsControl(e.KeyChar) = False Then
        If e.KeyChar <> ControlChars.Back Then
            If allowedChars.IndexOf(e.KeyChar) = -1 Then
                ' Invalid Character, notify clear and return
                e.Handled = True    'Set to True to 'swallow' the keypress and prevent the TextChanged event from firing.
                MsgBox("Numbers only", MsgBoxStyle.Exclamation)
                txtAmount.Text = ""
                txtAmount.Focus()
            End If
        End If
    End If
End Sub

Private Sub txtAmount_TextChanged(sender As Object, e As EventArgs) Handles TextBox2.TextChanged
    lblResult.Text = NumberToText(txtAmount.Text)
End Sub

Public Function NumberToText(input As String) As String
    'Convert value of amount to words here
End Function

您还可能希望使用MaskedTextBox来进行自动验证。

答案 1 :(得分:0)

这是我正在使用的解决方案,可能有点杂乱无章,但它可以起作用;

Private nonNumberEntered As Boolean = False
Private Sub txtAmount_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtAmount.KeyPress
    'Only allowed characters
    Dim allowedChars As String = "0123456789."

    If Char.IsDigit(e.KeyChar) = False And Char.IsControl(e.KeyChar) = False Then
        If e.KeyChar <> ControlChars.Back Then
            If allowedChars.IndexOf(e.KeyChar) = -1 Then
                ' Invalid Character, notify clear and return
                nonNumberEntered = True    'Set to True to 'swallow' the keypress and prevent the TextChanged event from firing.
                MsgBox("Numbers only", MsgBoxStyle.Exclamation)
                txtAmount.Text = ""
                txtAmount.Focus()
                lblResult.Text = ""
            End If
        End If
    End If
    'If shift key was pressed, it's not a number.
    If Control.ModifierKeys = Keys.Shift Then
        nonNumberEntered = True
        txtAmount.Text = ""
        txtAmount.Focus()
    End If
End Sub
Private Sub txtAmount_TextChanged(sender As Object, e As EventArgs) Handles txtAmount.TextChanged
    'Call the function to create a text line out of the numbers
    'Regex to ensure the string contains numbers
    Dim t As TextBox = sender
    Dim foo As Decimal
    If Decimal.TryParse(txtAmount.Text, foo) Then
        'data is good
        Dim re As New Text.RegularExpressions.Regex("\d")
        If re.IsMatch(txtAmount.Text) Then
            If nonNumberEntered = False Then
                Dim newNum = txtAmount.Text.Trim
                'If there are any leading weird . in the string
                newNum = newNum.TrimStart(".")
                Dim newStr As String
                'Build the array
                Dim newDec As String() = newNum.Split(New Char() {"."c})
                If newNum.Contains(".") Then
                    newStr = NumberToText(newDec(0))
                    lblResult.Text = newStr & " Dollars and " & newDec(1) & "/100 "
                Else
                    newStr = NumberToText(newDec(0))
                    lblResult.Text = newStr & " Dollars and 00/100 "
                End If

            End If
        End If
    Else
        'data is bad
        nonNumberEntered = False
        txtAmount.Text = ""
        txtAmount.Focus()
        lblResult.Text = ""
    End If

End Sub

请注意,在textChanged中,我正在检查值是否实际上是一个数字(如果是ot),请清除内容并继续操作。在textChanged中,我还允许使用小数点,但没有其他内容,然后清除所有使用户重新开始的内容。简单但有效……

答案 2 :(得分:0)

好,克里斯,你很近。我需要做的是设置e.KeyChar =“”,然后将and捕获在KeyPress中。所以这是我按预期工作的最终解决方案。

Private Sub cbCheckAmount_KeyPress(sender As Object, e As KeyPressEventArgs) Handles cbCheckAmount.KeyPress
    'Only allowed characters
    Dim allowedChars As String = "0123456789."
    If Char.IsDigit(e.KeyChar) = False And Char.IsControl(e.KeyChar) = False Then
        If e.KeyChar <> ChrW(Keys.Return) Or e.KeyChar <> ChrW(Keys.Tab) Then
            If e.KeyChar <> ControlChars.Back Or e.KeyChar <> ControlChars.Tab Then
                If allowedChars.IndexOf(e.KeyChar) = -1 Then
                    ' Invalid Character, notify clear and return
                    nonNumberEntered = True    'Set to True to 'swallow' the keypress and prevent the TextChanged event from firing.
                    MsgBox("Numbers only", MsgBoxStyle.Exclamation)
                    cbCheckAmount.Text = ""
                    cbCheckAmount.Focus()
                    lblTotalText.Text = ""
                    e.KeyChar = ""
                    nonNumberEntered = False
                End If
            End If
        End If
    End If

    'If shift key was pressed, it's not a number.
    If Control.ModifierKeys = Keys.Shift Then
        nonNumberEntered = True
        cbCheckAmount.Text = ""
        cbCheckAmount.Focus()
    End If

End Sub
Private Sub cbCheckAmount_TextChanged(sender As Object, e As EventArgs) Handles cbCheckAmount.TextChanged
    'Call the function to create a text line out of the numbers
    'Regex to ensure the string contains numbers
    Dim t As ComboBox = sender
    Dim foo As Decimal
    If nonNumberEntered = False Then
        If Decimal.TryParse(cbCheckAmount.Text, foo) Then
            'data is good
            Dim re As New Text.RegularExpressions.Regex("\d")
            If re.IsMatch(cbCheckAmount.Text) Then
                If nonNumberEntered = False Then
                    Dim newNum = cbCheckAmount.Text.Trim
                    'If there are any leading weird . in the string
                    newNum = newNum.TrimStart(".")
                    Dim newStr As String
                    'Build the array
                    Dim newDec As String() = newNum.Split(New Char() {"."c})
                    If newNum.Contains(".") Then
                        newStr = NumberToText(newDec(0))
                        lblTotalText.Text = newStr & " Dollars and " & newDec(1) & "/100 "
                    Else
                        newStr = NumberToText(newDec(0))
                        lblTotalText.Text = newStr & " Dollars and 00/100 "
                    End If
                End If
            End If
        End If
    Else
        'data is bad
        nonNumberEntered = True
        cbCheckAmount.Text = ""
        'cbCheckAmount.Focus()
        'lblTotalText.Text = ""
    End If

End Sub