Tuesday, February 5, 2013

.NET KeyPress Events


VB.NET Keypress Events
While messing around with the blog I found that one of the most viewed pages on here is the VBA Keypress event. If that many people are looking for it in VBA, there has to be a few who need it in .NET. I use it from time to time, primarily to handle the pasting of data from the clipboard into a datagridview, so I will share that as well.

The first piece is the most difficult, not because of complex code, but for remembering to do it. On your form go to your properties window and change the KeyPreview property to True. I never remember that part, and when I do I never remember the name. The help window for the property states “KeyPreview-Determines whether keyboard events for controls on the form are registered with the form.” In my own words “it turns on key press events”.

That was the hard part (it will be the next time you try this), the next part is a little confusing at first. Create a KeyPress event for your form. For those who don’t know how, there are 2 dropdowns just above your Public Class Form1 line of code, select (Form1 Events) from the left box, and KeyPress from the right dropdown.

You may have noticed a KeyDown event as well as the KeyPress event, there is a lot of confusion about which one to use and why. I will explain the differences in usage and translation as well as possible because each has a different purpose, and used in different ways.

Below I will provide a graphic showing which keys trigger which an event. If you want to remind yourself in the future or have other keys to test you can create an app with a couple of labels named lblKeyDown and lblKeyPress and test them yourself with the below.
The form:



 The Code:
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
        lblKeyDown.Text = e.KeyCode
End Sub

Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles Me.KeyPress
        lblKeyPress.Text = "KeyPress" & e.KeyChar
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        lblKeyDown.Text = ""
        lblKeyPress.Text = ""
End Sub

Just  run the app and start smashing keys.
Here is the map, read below about modifiers (shift, control, alt)

KeyPress and KeyDown Event Triggers
KeyPress can probably best be summed up by saying that its’ events are triggered by character keys.
Here is a picture of the keys that trigger the events:



KeyDown on the other hand fires and event for every key I have except the Windows key. One problem that can arise is the use of modifier keys, for example when you want to copy using control C you get one event for the control key and another for the C key. However this is easily handled.
One last odd thing, KeyPress returns the actual character of the key that was pressed while KeyDown returns a KeyCode. For example if you press the “j” key, KeyPress returns “j”, but KeyDown returns 74. You have to use e.KeyCode.toString to get the actual value.

For KeyDown you may want to handle modifiers, if you don’t then A)you won’t know if one was pressed and B)depending on your usage it will send the modifier as a key when you don’t really want it. This is pretty simple though, you just use e.Control, e.Shift etc. to determine if the modifier is pressed. For example say you only want to handle a Control+C, here is how you do it:

If e.Control = True Then
            If e.KeyCode.ToString = "C" Then
                MsgBox("Control+C pressed")
            End If
End If

That should cover most scenario’s you will need. Now I’ll show you how to handle the pasting of data to a datagridview.

Paste to Datagridview
Assuming you have a datagridview named datagridview1, and you have the appropriate columns already added, the following code will paste the values in your clipboard to the datagridview.

Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
        If e.Control = True Then
            If e.KeyCode.ToString = "V" Then
                PasteClipboard()
            End If
        End If
    End Sub
    Private Sub PasteClipboard()
        Dim s As String = Clipboard.GetText()       'Get clipboard data as a string
        Dim rows() As String = s.Split(ControlChars.NewLine) 'Split into rows
        Dim I, j As Integer                                             
        Try
            For I = 0 To rows.Length - 1
                'Add new row
                If Me.DataGridView1.Rows.Count < rows.Length Then Me.DataGridView1.Rows.Add()

                'Split row into cells
                Dim bufferCell() As String = rows(i).Split(ControlChars.Tab)
                'Copy to datagrid
                For j = 0 To bufferCell.Length - 1
                    'Remove line feed characters
                    If bufferCell(j).ToString.Contains(ControlChars.Lf) Then
                    bufferCell(j) = bufferCell(j).ToString.Replace(ControlChars.Lf, "")
                    End If
                    Me.DataGridView1.Item(j, I).Value = bufferCell(j)
                Next
            Next
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try

End Sub