Índice de la sección dedicada a .NET (en el Guille) Cómo... en .NET

Detectar la pulsación de teclas
y cambiar el código de la tecla pulsada y otras cosillas

Código para Visual Basic.NET (VB.NET)

Código para C Sharp (C#)


Publicado el 14/Nov/2002
Actualizado el 14/Nov/2002


Si has usado cualquier versión de Visual Basic anterior a .NET, seguramente sabrás cómo saber que tecla se ha pulsado en un textbox (u otro control), interceptando los eventos KeyPress o KeyDown/KeyUp.
En el primer evento, ese código estaba indicado por el parámetro KeyAscii, en los otros dos, el código lo indicaba el parámetro KeyCode.

En el caso del evento KeyPress, podíamos saber si se había pulsado la tecla Intro con una comparación como esta:
If KeyAscii = vbKeyReturn Then
Y a continuación, (para evitar el pitido), asignábamos un valor cero a KeyAscii:
KeyAscii = 0

Pero con el .NET Framework, (no sólo con VB, también con C# u  otro lenguaje), esto no es posible... al menos de la misma forma que se hacía con el Visual Basic clásico.

En el caso del evento KeyPress, para saber qué tecla se ha pulsado, debemos usar e.KeyChar, (que sería el equivalente al parámetro KeyAscii en VB clásico), pero la propiedad KeyChar es de solo lectura, por tanto no se puede asignar un valor a dicha propiedad... aunque esto en teoría no es problema, ya que te mostraré la solución.

El hecho de asignar un valor cero a KeyAscii es para indicar que no se debe tener en cuenta la pulsación de dicha tecla, esto en .NET se hace asignando un valor verdadero a la propiedad Handled del objeto e:
e.Handled = True
Con esto indicamos que esa tecla ha sido "manejada" por nuestro evento y se ignorará.

Pero en otras ocasiones, lo que nos interesa es cambiar la tecla pulsada por otra diferente.
Por ejemplo, si en nuestra configuración regional tenemos que los decimales se representan por la coma, podíamos querer que al pulsar en el punto, ésta pulsación se convierta en una coma.
Nuevamente en Visual Basic clásico era tan simple como esto:
If KeyAscii = Asc(".") Then KeyAscii = Asc(",")
Es decir, si la tecla es el punto, cambiarla por la coma.
Pero como acabamos de ver, en .NET no se puede asignar un nuevo valor a la propiedad KeyChar, pero para solucionarlo, podemos echar mano de la clase SendKeys (a diferencia del VB clásico, ahora no es una función de VB sino una clase de .NET Framework) y lanzar la pulsación de la tecla que nos interese:
SendKeys.Send(",")
Pero si hacemos sólo esto, nos encontramos con dos pulsaciones: el punto que el usuario ha pulsado y la coma que nosotros hemos "enviado" al teclado.
La solución es la misma que acabamos de ver anteriormente: indicar que el usuario no ha pulsado nada: e.Handled = True, con esto sólo quedará la tecla que nosotros hemos enviado con SendKeys.

A continuación te muestro el código de un formulario de prueba, tanto para VB como para C#, en el que además de ver esto de la pulsación y cómo saber que tecla se ha pulsado (y cambiar el código de la tecla pulsada), también veremos cómo detectar la pulsación de la tecla suprimir en un ListBox y saber cómo averiguar la tecla pulsada, ya que el tipo de datos de KeyChar es del tipo Char y en .NET esto de convertir teclas normales y Char es un poco "rollo".

Además verás cómo seleccionar todo el texto de un textbox cuando el control toma el foco.

 

Cómo saber el código de la tecla pulsada:
En Visual Basic es relativamente fácil, en C# aún lo es más, si usamos los códigos de "escape".
Veamos primero cómo hacerlo con VB:
Podemos saber qué tecla se ha pulsado usando tanto con la función ChrW como con el método ToChar de la clase Convert, además de usar la conversión de una cadena a char usando la letra C después de la cadena, aunque esto sólo se puede usar con teclas normales (las que podemos representar desde el teclado):

If
e.KeyChar = Convert.ToChar(Keys.Return)
Then

If
e.KeyChar = ChrW(Keys.Return) Then

If
e.KeyChar = "."c Then

 

En C# podemos hacerlo de estas dos formas:

if
( e.KeyChar == '\r' )

if( e.KeyChar == Convert.ToChar('\r') )

 

Aquí tienes el código para los dos ejemplos (en VB y en C#): pulsarTeclas.zip 14.3 KB


Código para Visual Basic.NET (VB.NET)Saber que tecla se ha pulsado en un textbox y otras cosillas (VB)

Este es el código para Visual Basic .NET

Private Sub txtNumero_KeyPress(ByVal sender As Object, _
                ByVal e As System.Windows.Forms.KeyPressEventArgs) _
                Handles txtNumero.KeyPress
    ' Si se pulsa la tecla Intro, pasar al siguiente
    If e.KeyChar = Convert.ToChar(Keys.Return) Then
        'If e.KeyChar = ChrW(Keys.Return) Then
        e.Handled = True
        txtFecha.Focus()
    ElseIf e.KeyChar = "."c Then
        ' si se pulsa en el punto se convertirá en coma
        e.Handled = True
        SendKeys.Send(",")
    End If
End Sub
'
Private Sub txtFecha_KeyPress(ByVal sender As Object, _
                ByVal e As System.Windows.Forms.KeyPressEventArgs) _
                Handles txtFecha.KeyPress
    Select Case e.KeyChar
        Case Convert.ToChar(Keys.Return)  'ChrW(Keys.Return)
            e.Handled = True
            btnAdd.Focus()
        Case "."c, ","c, "-"c
            ' si se pulsa en estos caracteres, se convertirá en /
            e.Handled = True
            SendKeys.Send("/")
    End Select
End Sub
'
Private Sub txtNumero_Enter(ByVal sender As Object, _
                ByVal e As System.EventArgs) _
                Handles txtNumero.Enter, txtFecha.Enter
    ' Al recibir el foco, seleccionarlo todo
    CType(sender, TextBox).SelectAll()
End Sub
'
Private Sub ListBox1_KeyDown(ByVal sender As Object, _
                ByVal e As System.Windows.Forms.KeyEventArgs) _
                Handles ListBox1.KeyDown
    ' Si se pulsa en Supr, borrar el elemento seleccionado
    If e.KeyCode = Keys.Delete Then
        ListBox1.Items.Remove(ListBox1.SelectedItem)
    End If
End Sub
'
Private Sub btnAdd_Click(ByVal sender As Object, _
                ByVal e As System.EventArgs) _
                Handles btnAdd.Click
    ' Añadir el contenido de las cajas al listbox
    ListBox1.Items.Add(txtNumero.Text & ", " & txtFecha.Text)
    txtNumero.Focus()
End Sub
'
Private Sub btnCerrar_Click(ByVal sender As Object, _
                ByVal e As System.EventArgs) _
                Handles btnCerrar.Click
    ' cerrar el formulario
    ' (si este es el único formulario, también se cerrará el ejecutable)
    Me.Close()
End Sub

Código para C Sharp (C#)Saber que tecla se ha pulsado en un textbox y otras cosillas (C#)

Este es el código para C#

private void txtNumero_KeyPress(object sender, 
                System.Windows.Forms.KeyPressEventArgs e)
{
    // Si se pulsa la tecla Intro, pasar al siguiente
    //if( e.KeyChar == Convert.ToChar('\r') ){
    if( e.KeyChar == '\r' ){
        e.Handled = true;
        txtFecha.Focus();
    }else if( e.KeyChar == '.' ){
        // si se pulsa en el punto se convertirá en coma
        e.Handled = true;
        SendKeys.Send(",");
    }
}

private void txtFecha_KeyPress(object sender, 
                System.Windows.Forms.KeyPressEventArgs e)
{
    //
    switch(e.KeyChar){
        case '\r':
            e.Handled = true;
            btnAdd.Focus();
            break;
        case '.':
        case ',':
        case '-':
            // si se pulsa en estos caracteres, se convertirá en /
            e.Handled = true;
            SendKeys.Send("/");
            break;
    }
}

private void btnAdd_Click(object sender, System.EventArgs e)
{
    // Añadir el contenido de las cajas al listbox
    ListBox1.Items.Add(txtNumero.Text + ", " + txtFecha.Text);
    txtNumero.Focus();
}

private void btnCerrar_Click(object sender, System.EventArgs e)
{
    // cerrar el formulario
    // (si este es el único formulario, también se cerrará el ejecutable)
    this.Close(); 
}

private void ListBox1_KeyDown(object sender, 
                System.Windows.Forms.KeyEventArgs e)
{
    // Si se pulsa en Supr, borrar el elemento seleccionado
    if( e.KeyCode == Keys.Delete )
    {
        ListBox1.Items.Remove(ListBox1.SelectedItem);
    }
}

private void txtNumero_Enter(object sender, System.EventArgs e)
{
    // Al recibir el foco, seleccionarlo todo
    ((TextBox)sender).SelectAll();
}

la Luna del Guille o... el Guille que está en la Luna... tanto monta...