Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Handling Ctrl_V with a keypress test 1

Status
Not open for further replies.

CraigBest

Programmer
Aug 1, 2001
545
US
Hi Folks

I have a textbox that uses a KeyPress event to test for numeric values; anything typed in other than a number generates a beep and the character is ignored. Unfortunately it seems that it also short-circuits the text box's ability to accept a paste or Ctrl_V command to paste in a series of numbers like a product number. I personally don't care but the users are complaining...

I figure the answer is to check for and allow a ctrl_V or paste operation to take place and only run the test if an actual single key is pressed. I realize that it may allow the users to put anything in the field including spaces or letters, but they insist that's the way they want it!

Anyway, I'm having trouble trying to figure out how to test for the paste commands in the KeyPress routine. Does anyone have a suggestion on how I might do this?

Thanks



CraigHartz
 
There is a difficulty in using the KeyPress routine.

The only parameter for identification is the KeyChar properties. Which limits what you can do.

It would be better trapping these in the KeyDown event.
Code:
    Private Sub TextBox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
        If e.Control AndAlso e.KeyCode = Keys.A Then
            'do this
        ElseIf e.KeyCode = Keys.A Then
            e.SuppressKeyPress = True
        End If
    End Sub
That suppresses the A key, but allows Ctrl+A.

You've got to be careful though, on not relying completely on trapping the keypresses AND allowing pasting. Pasting bypasses the Keypress and you could end up with disallowed characters in your textbox.
 
That's helpful, thanks. But I'm having some trouble with the KeyCode property as opposed to the KeyChar property in the Keypress event. Is there a way to get the keyChar value out of the KeyCode information you get in KeyUp or KeyDown?

I only ask because the test is a method in a class that expects a Char value, and it doesn't like any of the Code values from KeyCode, which appear to be numeric.

Thanks

CraigHartz
 
If all you need to allow are numeric characters 0-9, then the following should work:
Code:
If e.KeyValue < 48 Or e.KeyValue > 57 Then
    e.SuppressKeyPress = True
End If
Using the ASCII values this blocks out anything other than a numeric keypress.

Of course this could block out other keys as well - such as the arrow keys, or the home/end keys, etc...
 
Yeah, I did think about that - but we have these annoying standards I have to work within, and I'm not supposed to write my own tests, but use the 'canned' ones so we always have a single place to look for the test. Actually it works great, but it is keyed to the KeyPress event (and subsequently the KeyChar type) so without being able to convery the Value to a KeyChar, I'm boned. :)

CraigHartz
 
... And don't think I can't see the irony of allowing them to paste anything into the text box while restricting them to certain keys when they type... ;-)

CraigHartz
 
I think I've got a solution that will work.

Use both methods, the KeyPress and your method to restrict the characters, and the KeyDown to check for the Ctrl+V.

As you method blocks the paste from working, upon detecting the key combination you can implement the paste procedure yourself - which also allows you to verify the data before putting it into the textbox.

Code:
    Private Sub TextBox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown
        If e.Control AndAlso e.KeyCode = Keys.V Then
            'do paste
            TextBox1.SelectedText = Clipboard.GetText()
        End If
    End Sub

    Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
        Dim strNum As String = "0123456789"
        e.Handled = (strNum.IndexOf(e.KeyChar) = -1)
    End Sub
 
Bovrik, Thanks! Actually it turns out that placing the Clipboard.GetText() in the KeyDown event was enough to make the whole thing work. I can continue using the Canned Test in the KeyPress event too (it just makes a beep sound, but it does not prevent the paste operation from occurring). That's good enough for me! Thank you so much.



CraigHartz
 
If you want to disallow pasting of invalid values:
Code:
Public Class Form1

    Private txtNumbersOnlyText As String
    Private txtNumbersOnlyStart As Integer
    Private txtNumbersOnlyLength As Integer

    Private Sub txtNumbersOnly_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtNumbersOnly.KeyDown
        txtNumbersOnlyStart = txtNumbersOnly.SelectionStart
        txtNumbersOnlyLength = txtNumbersOnly.SelectionLength
    End Sub

    Private Sub txtNumbersOnly_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtNumbersOnly.TextChanged
        Static wasInvalid As Boolean = False

        If (wasInvalid) Then
            wasInvalid = False
            Exit Sub
        End If

        For Each c As Char In txtNumbersOnly.Text
            If (c < "0"c OrElse c > "9"c) Then
                My.Computer.Audio.PlaySystemSound(Media.SystemSounds.Beep)
                wasInvalid = True
            End If
        Next

        If (wasInvalid) Then
            txtNumbersOnly.Text = txtNumbersOnlyText
            txtNumbersOnly.SelectionStart = txtNumbersOnlyStart
            txtNumbersOnly.SelectionLength = txtNumbersOnlyLength
        Else
            txtNumbersOnlyText = txtNumbersOnly.Text
        End If

    End Sub
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top