2010-07-01 16 views
8

Actualmente estoy manejando el evento KeyDown de un control DataGridView. Una de las columnas está llena de valores calculados y quiero que el usuario pueda anular el valor de la celda si lo desea.Evento KeyDown: cómo saber fácilmente si la tecla presionada es numérica.

Cuando el usuario presiona una tecla numérica, la celda entra en EditMode y le permite al usuario anular el valor. Si la clave no es numérica, no pasa nada ...

Eso está funcionando bastante bien ... el problema es que me parece feo el código ... Parece que no puedo encontrar una manera ordenada de manejar todas las teclas numéricas en una sola condición, así que he hecho una construcción de caja de conmutación para hacer frente a todos los posibles teclas numéricas, como esto:

   switch (e.KeyCode) 
       { 
        case Keys.D0: 
        case Keys.D1: 
        case Keys.D2: 
        case Keys.D3: 
        case Keys.D4: 
        case Keys.D5: 
        case Keys.D6: 
        case Keys.D7: 
        case Keys.D8: 
        case Keys.D9: 
        case Keys.Decimal: 
        case Keys.NumPad0: 
        case Keys.NumPad1: 
        case Keys.NumPad2: 
        case Keys.NumPad3: 
        case Keys.NumPad4: 
        case Keys.NumPad5: 
        case Keys.NumPad6: 
        case Keys.NumPad7: 
        case Keys.NumPad8: 
        case Keys.NumPad9: 

         [code to make the cell go to editMode, etc...] 

Claro, es que funciona, pero tiene que haber una mejor y una forma más corta, ¿verdad?

Todo lo que podía encontrar a través de Google es convertir e.KeyCode a un char, pero cuando se utiliza el teclado numérico, que va da las cartas, incluso para los valores numéricos ...

Gracias.

Respuesta

10

Si se utiliza el evento KeyPress, la firma evento tiene un KeyPressEventArgs con un miembro KeyChar que g te da el personaje para las teclas del teclado numérico. Puedes hacer un TryParse sobre eso para averiguar si es un número o no.

private void Form1_KeyPress(object sender, KeyPressEventArgs e) 
{ 
    int i; 
    if (int.TryParse(e.KeyChar.ToString(), out i)) 
    { 
     MessageBox.Show("Number"); 
    } 
} 
+4

O incluso e.KeyChar.IsDigit()? – Rawling

+0

Gracias Tim y Rawling. Esa es la solución que fui con. también tengo que manejar un evento de tecla dEL en KeyDown ... hubiera preferido mantener todo al mismo lugar, pero este código se ve de lejos el mejor. Gracias a todos los demás también. –

1

Por msdn help page que utilizan este código en su ejemplo:

// Determine whether the keystroke is a number from the top of the keyboard. 
if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9) 

...

// Determine whether the keystroke is a number from the keypad. 
if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9) 
+0

@Rawling, @tanascius: gracias, yo pensaba en eso, pero yo pensó que era una mala práctica realizar evaluaciones de rango contra enumeraciones? Acepto que el hecho de que proviene de MSDN lo hace relativamente seguro, pero después de todo, no sería la primera vez que veríamos un código de ejemplo incorrecto de MSDN ... ¿Hay algo que garantice que los valores siempre será contiguo? Después de todo, tenemos enumeraciones para no confiar en los valores subyacentes. Al realizar dicho control, ¿no estoy confiando en el hecho de que estos valores de enumeraciones serán contiguos el uno al otro? Gracias. –

+0

Por malo que pueda ser una práctica, espero que, dado que Microsoft está usando eso en sus documentos, se cuidarán de mantener el comportamiento consistente. Si puede cambiar al evento KeyPress en lugar de KeyDown, puede usar la solución que proporcioné. –

+0

Sí, si hay una razón para no hacer eso, la solución de Tim es buena, y también hace mucho más obvio lo que estás tratando de hacer. – Rawling

13

Trate

if ((e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) || 
    (e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9) || 
    e.KeyCode == Keys.Decimal) 
{ 
    // Edit mode 
} 
+0

marcado y es correcto, pero - telerikGrid no es compatible con KeyPress ... esto funciona ! – Muds

0
void dataGridView1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) 
{ 
    // Used this to find they key values. 
    //label1.Text += e.KeyValue; 

    // Check if key is numeric value. 
    if((e.KeyValue >= 48 && e.KeyValue <= 57) || (e.KeyValue >= 97 && e.KeyValue <= 105)) 
     System.Console.WriteLine("Pressed key is numeric"); 
} 
+1

Cuidado con el uso de este método, ya que no toma en cuenta los valores teclado numérico (NumPad0 = 96 = 'd') –

6

Por qué códigos de teclas de uso, cuando se puede usar esto:

void Control_KeyPress(object sender, KeyPressEventArgs e) 
    { 

     if (Char.IsDigit(e.KeyChar)) 
     { 
      //do something 
     } 
     else 
     { 
      //do something else 
     } 
    } 

Es más limpio e incluso si Microsoft decide cambiar todas las enumeraciones vlue, todavía funcionaría

4

solución de Sorcerer86pt fue el más simple, sin embargo, cuando un usuario presiona una tecla de control, como retroceso, se rompe. Para resolver ese problema, puede utilizar el siguiente fragmento:

void KeyPress(object sender, KeyPressEventArgs e) 
{  
    if(!Char.IsNumber(e.KeyChar) && !Char.IsControl(e.KeyChar)) 
    { 
     //The char is not a number or a control key 
     //Handle the event so the key press is accepted 
     e.Handled = true; 
     //Get out of there - make it safe to add stuff after the if statement 
     return; 
    } 
    //e.Handled remains false so the keypress is not accepted 
} 

Si está utilizando WPF, puede encontrarse con que un cuadro de texto no tiene un evento KeyPressed. Para solucionar esto, utilicé el siguiente código.

void ValidateKeyPress(object sender, KeyEventArgs e) 
{ 
    char keyPressed = WPFUtils.Interop.Keyboard.GetCharFromKey(e.Key); 
    if (!Char.IsNumber(keyPressed) && !Char.IsControl(keyPressed)) 
    { 
     //As above 
     e.Handled = true; 
     return; 
    } 
} 

Usted puede notar la extraña llamada de función WPFUtils.Interop.Keyboard.GetCharFromKey(e.Key) esta es una de las funciones útiles que he recogido. Lo puedes encontrar here.

+0

sí que es mejor de esta manera. – Sorcerer86pt

2

Obtenga el último carácter de la tecla que será el número si se presionó un número. Este método funciona con eventos KeyDown que no necesitan ninguna otra condición.

Sólo tiene que llamar este método estático y pasar en la clave para comprobar

public static bool IsNumber(Keys key) 
{ 
    string num = key.ToString().Substring(key.ToString().Length - 1); 
    Int64 i64; 
    if (Int64.TryParse(num, out i64)) 
    { 
    return true;    
    } 
    return false; 
} 
1

Un poco más versión condensada:

private void KeyPress(object sender, KeyPressEventArgs e) 
    { 
     e.Handled = !Char.IsDigit(e.KeyChar); // only allow a user to enter numbers 
    } 
+0

solo como nota adicional, esto no permitiría presionar la tecla de retroceso, junto con cualquier tecla que no sean números. – Takarii

Cuestiones relacionadas