7 Replies - 208 Views - Last Post: 28 October 2018 - 02:49 PM Rate Topic: -----

#1 mgfranz   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 27-October 18

Capture <Tab> and <Return> key in TextChanged Event

Posted 27 October 2018 - 02:45 PM

Is it possible to catch the Enter or Tab key in the TextChanged Event?

I am entering a numeric only value on a comboBox, but once this value has been validated I want the user to be able to either Tab or Enter out of the CB once validated, is this possible from within the TextChanged? Here's my code;

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()
                    cbDollarAmount.Text = ""
                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 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

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

    End Sub


What happens is that which each valid numeric to cbCheckAmount, the sub NumberToText is called and submits a text value to lblTotalText, the code works fine, but how do I allow the user to either <Tab> or <Cr> out of the cbCheckAmount to cbMemoBox and retain the values in both cbCheckAmount and lblTotalText? I can capture the <Tab> and <Cr> using PreviewKeyDown, but when I catch either a <Tab> or <Cr> the TextChanged sets nonNumberEntered to False and clears the fields.

Private Sub cbCheckAmount_PreviewKeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles cbCheckAmount.PreviewKeyDown
        If e.KeyData = Keys.Tab Or e.KeyCode = Keys.Enter Then
            e.IsInputKey = True
            If e.KeyData = Keys.Tab Then
                MsgBox("Tab key pressed")
            ElseIf e.KeyCode = Keys.Enter Then
                MsgBox("Enter key pressed")
                'cbMemoBox.Focus()
            End If
        End If
    End Sub


Also, if I enter a valid number into cbCheckAmount and try to "Click" out of it into another control, cbCheckAmount and lblTotalText are cleared and focus is set to cbCheckAmount as if nonNumberEntered is set to False. So, how can I allow the <Tab>, <Cr> and be able to click out of cbCheckAmount and retain values?

Is This A Good Question/Topic? 0
  • +

Replies To: Capture <Tab> and <Return> key in TextChanged Event

#2 snoopy11   User is offline

  • Engineering ● Software
  • member icon

Reputation: 1554
  • View blog
  • Posts: 4,930
  • Joined: 20-March 10

Re: Capture <Tab> and <Return> key in TextChanged Event

Posted 27 October 2018 - 03:51 PM

Err yeah,

should be possible you would Overload your

Private Sub cbCheckAmount_TextChanged(sender As Object, e As EventArgs) Handles cbCheckAmount.TextChanged



to this

Private Overloads Sub cbCheckAmount_TextChanged(sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Input.KeyDown
        



then in your subroutine check for return key for example like this

If e.KeyCode = Keys.Return Then

....

End If



or Keys.Tab if you must use the Tab key personally I prefer the Return key for input :)
Was This Post Helpful? 0
  • +
  • -

#3 mgfranz   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 27-October 18

Re: Capture <Tab> and <Return> key in TextChanged Event

Posted 27 October 2018 - 04:08 PM

View Postsnoopy11, on 27 October 2018 - 03:51 PM, said:

Err yeah,

should be possible you would Overload your

Private Sub cbCheckAmount_TextChanged(sender As Object, e As EventArgs) Handles cbCheckAmount.TextChanged



to this

Private Overloads Sub cbCheckAmount_TextChanged(sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Input.KeyDown
        



then in your subroutine check for return key for example like this

If e.KeyCode = Keys.Return Then

....

End If



or Keys.Tab if you must use the Tab key personally I prefer the Return key for input :)/>/>/>


Private Overloads Sub cbCheckAmount_TextChanged(sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Input.KeyDown


Input.KeyDown

Error BC30506 Handles clause requires a WithEvents variable defined in the containing type or one of its base types.
Was This Post Helpful? 0
  • +
  • -

#4 IronRazer   User is offline

  • Custom Control Freak
  • member icon

Reputation: 1526
  • View blog
  • Posts: 3,848
  • Joined: 01-February 13

Re: Capture <Tab> and <Return> key in TextChanged Event

Posted 27 October 2018 - 04:38 PM

Just use the combobox's KeyDown event to detect the Return/Enter key. From there you can set the Handled and SuppressKeyPress properties to True so that the key will not be processed any further by the ComboBox. That stops the TextChanged event from firing when enter is detected. From there you can use the SelectNextControl method to select the next control on the form.

As far as the Tab key goes, that should already be selecting the next control without even using any code. That is the normal function of the Tab key with a Form and it's controls. So, perhaps you have code that is stopping that default functionality somehow.

Public Class Form1
    Private Sub ComboBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles ComboBox1.KeyDown
        If e.KeyCode = Keys.Enter Then
            e.SuppressKeyPress = True
            e.Handled = True
            Me.SelectNextControl(Me.ActiveControl, True, True, True, True)
        End If
    End Sub

    Private Sub ComboBox1_TextChanged(sender As Object, e As EventArgs) Handles ComboBox1.TextChanged
        MessageBox.Show("changed")
    End Sub
End Class


Was This Post Helpful? 0
  • +
  • -

#5 snoopy11   User is offline

  • Engineering ● Software
  • member icon

Reputation: 1554
  • View blog
  • Posts: 4,930
  • Joined: 20-March 10

Re: Capture <Tab> and <Return> key in TextChanged Event

Posted 27 October 2018 - 04:38 PM

Are you using VS2015 ? as this error seems to be invoked in that version of the compiler.

The code supplied works in vs2017 enterprise edition.

Also, no need for the large quote as I know what I said and everyone else reading it also knows what I said and you too know what I said so... no quoting just reply. :)
Was This Post Helpful? 0
  • +
  • -

#6 mgfranz   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 27-October 18

Re: Capture <Tab> and <Return> key in TextChanged Event

Posted 27 October 2018 - 04:57 PM

View PostIronRazer, on 27 October 2018 - 04:38 PM, said:

As far as the Tab key goes, that should already be selecting the next control without even using any code. That is the normal function of the Tab key with a Form and it's controls. So, perhaps you have code that is stopping that default functionality somehow.


If I set a Breakpoint in the cbCheckAmount_KeyPress event I can see that the <Tab> is not being allowed and is therefore clearing the fields and is holding control in cbCheckAmount.

If you need the entire Project you can get it here CheckPrint.zip

@snoopy11, yeah, VS2015. I guess I could checkout 2017.
Was This Post Helpful? 0
  • +
  • -

#7 IronRazer   User is offline

  • Custom Control Freak
  • member icon

Reputation: 1526
  • View blog
  • Posts: 3,848
  • Joined: 01-February 13

Re: Capture <Tab> and <Return> key in TextChanged Event

Posted 27 October 2018 - 05:19 PM

Well, I don't really have time to look through your whole project to find the reason, all I can say is that the Tab key is a command key that by default will switch focus between the controls, the ones that can contain focus anyways.

The only other easy way I could suggest which will allow you to handle the Tab key and Enter key yourself, before the ComboBox does, is by using the Form's ProcessCmdKey overrides function. Again, this will catch the Tab or Enter key, stop the ComboBox from receiving the key, and then select the next control on the form.
Public Class Form1

    Private Sub ComboBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles ComboBox1.KeyPress
        MessageBox.Show("keypress")
    End Sub

    Private Sub ComboBox1_TextChanged(sender As Object, e As EventArgs) Handles ComboBox1.TextChanged
        MessageBox.Show("changed")
    End Sub

    Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean

        'check if the ComboBox has focus and either the Enter key or Tab key was pressed....
        If ActiveControl Is ComboBox1 AndAlso (keyData = Keys.Enter OrElse keyData = Keys.Tab) Then

            Me.SelectNextControl(Me.ActiveControl, True, True, True, True) 'selects the next control on the form
            Return True 'return True so that the Combobox will not receive the key. This stops the TextChanged and KeyPress events from being raised for these two keys
        End If

        Return MyBase.ProcessCmdKey(msg, keyData)
    End Function
End Class


Was This Post Helpful? 0
  • +
  • -

#8 mgfranz   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 27-October 18

Re: Capture <Tab> and <Return> key in TextChanged Event

Posted 28 October 2018 - 02:49 PM

View PostIronRazer, on 27 October 2018 - 05:19 PM, said:

The only other easy way I could suggest which will allow you to handle the Tab key and Enter key yourself, before the ComboBox does, is by using the Form's ProcessCmdKey overrides function. Again, this will catch the Tab or Enter key, stop the ComboBox from receiving the key, and then select the next control on the form.


I think I got it. I had a couple of issues, first was that "e" was holding a bad character value so if a bad value is entered "e" would hold it, so I fixed that.

Then I added a If statement in KeyPress to catch a Tab or CR and allow them. At this time my code seems to be working, here is the new KeyPress and TextChanged events;

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

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1