2009-04-20 15 views
7

Esto parece algo que debería ser fácil, pero me está costando trabajo averiguar qué debe suceder aquí.¿Cómo convierto un valor enum de "Llaves" a un carácter "int" en C#?

En el controlador de eventos "KeyDown", si "e.KeyValue" es un número, quiero tratarlo como un número y almacenarlo como un int. Entonces, si presiono "8" en el teclado numérico, no quiero "Numpad8" Quiero el valor int 8 que puedo sumar o restar o lo que sea.

Entonces, ¿cómo convierto el KeyValue a un int?

Respuesta

14

me gustaría ir con esta solución:

int value = -1; 
if (e.KeyValue >= ((int) Keys.NumPad0) && e.KeyValue <= ((int) Keys.NumPad9)) { // numpad 
    value = e.KeyValue - ((int) Keys.NumPad0); 
} else if (e.KeyValue >= ((int) Keys.D0) && e.KeyValue <= ((int) Keys.D9)) { // regular numbers 
    value = e.KeyValue - ((int) Keys.D0); 
} 

... si el punto era conseguir que el valor numérico de la etiqueta de ellos clave que terminó rechazado en

+3

¿por qué no usar las enumeraciones en lugar de los números para que sea más legible? "> = (int) Keys.D0" y "> = (int) Keys.Numpad0" etc ... –

+4

Muchos números mágicos en este código. Usar las enumeraciones de Keys.X es mucho más claro. –

+0

Estaba pensando eso, pero esto es lo que necesitaba. ¡Gracias! –

2

Dependiendo de cuántas teclas esté rastreando, el método más simple sería crear un caso de selección (o cambiar la declaración en C# ¿Supongo?) Que verificaría el valor de su clave y dependiendo de ese valor asigna un valor a un entero que sea apropiado.

+0

Uf ... Puedo hacer eso, pero se siente tan sucio. Tendría que verificar los valores del teclado numérico y los otros números sobre el teclado. Parece mucho buscar algo que parece ser común. –

+1

Si bien puede parecerle así, me sorprendería bastante si esto fuera algo común. Lo más cercano que podría venir sería alguien analizando un valor numérico de una cadena que se ingresó. –

+0

La respuesta de Adam va más allá en la explicación. Si desea ASCII, puede obtener el valor sin mucha dificultad, pero si desea traducirlo a una representación de dígitos, tendrá que trabajar un poco. No todo se traducirá automágicamente en lo que tú quieras. – TheTXI

-3

int i = (int) e.KeyValue;

+0

Permítanme aclarar: Usando mi ejemplo del "teclado numérico 8" anterior, el valor int de eso es 104, entonces mi valor usando su código sería 104, pero realmente quiero que el valor sea 8. –

2

Si desea valores NUMERIC, tendrá que crear una declaración switch(e.KeyCode) y evaluar la clave y crear su propia int. No hay una forma simple de convertir un Keys en un valor numérico que represente el número en la clave. Lo más cercano que podría obtener podría ser el equivalente ASCII, que todavía tendría que ser traducido.

+0

matemática simple es mucho mejor que un interruptor para cada valor. Por favor verifique a continuación. –

+0

Has publicado tu propia respuesta ... realmente no es necesario comentar en otros para atraer la atención hacia los tuyos. –

+0

Gracias Adam. Pero esa no era mi intención. Si alguien leyó esta publicación y le gustó, quería alejarlos de la idea de declaración de cambio si encontraron mi respuesta o no. –

1

Podría simplemente escuchar. para el evento KeyPress en su lugar? Le dará al personaje que fue realmente presionado.

+0

Aún no sabes cómo usar esa información. Supongo que quiere decir que debería usar el evento KeyPress y hacer un int.TryParse en él. –

0

KeyValue representa el código de carácter para la tecla que se presionó. Para obtener su valaue numérico, debe encontrar el carácter de la tecla que se presionó, luego analizarlo de un carácter a un número entero.

Algo así como Convert.ToInt32 (e.KeyCode.ToString())

1

Esta función hará lo que quiere:

private int GetKeyValue(int keyValue) 
{ 
    if (keyValue >= 48 && keyValue <= 57) 
    { 
     return keyValue - 48; 
    } 
    else if (keyValue >= 96 && keyValue <= 105) 
    { 
     return keyValue - 96; 
    } 
    else 
    { 
     return -1; // Not a number... do whatever... 
    } 
} 

Llámelo así:

private void Form1_KeyDown(object sender, KeyEventArgs e) 
{ 
    int num = GetKeyValue(e.KeyValue); 
} 
+0

Hay demasiada codificación en esta función para ser un código realmente bueno. Busque a continuación una versión modificada. –

+0

Es cierto, pero esta es una función tan trivial que los comentarios muy simples informarían a cualquiera exactamente lo que hace –

5

Algo así debería funcionar bien: (Editado)

int keyVal = (int)e.KeyValue; 
int value = -1; 
if ((keyVal >= (int)Keys.D0 && keyVal <= (int)Keys.D9) 
{ 
    value = (int)e.KeyValue - (int)Keys.D0; 
} 
else if (keyVal >= (int)Keys.NumPad0 && keyVal <= (int)Keys.NumPad9) 
{ 
    value = (int)e.KeyValue - (int)Keys.NumPad0; 
} 
+0

+1 para realmente usar las enumeraciones! ¿Cómo es que nadie más quiere hacer eso? –

+0

tiene que restar según el rango (D0 o NumPad0, no solo D0). –

+0

también funciona para WPF con pequeñas modificaciones :) –

0

O crear un método de extensión y llamarlo como

private void Form1_KeyDown(object sender, KeyEventArgs e) 
{  
    int num = e.KeyValue.GetKeyValue(); 
} 

donde el método de extensión es

public static class MyExtensions 
{ 
    public static int GetKeyValue(this int keyValue) 
    { 

     if (keyValue >= 48 && keyValue <= 57) 
     { 
      return keyValue - 48; 
     } 
     else if (keyValue >= 96 && keyValue <= 105) 
     { 
      return keyValue - 96; 
     } 
     else 
     { 
      return -1; // Not a number... do whatever... } 

     } 
    } 
} 
4

Datos: teclado tiene teclas. Algunas teclas representan números y otras no.

Problema (reformulado): Rendimiento de un valor numérico representado por una tecla, si la tecla representa un número.

Para resolver el problema, es necesario saber qué teclas (fuera del conjunto de todas las teclas) representan los números así como el valor numérico exacto que representa cada tecla (número).

Que yo sepa, no existe una manera fácil de obtener una asignación de este tipo del marco.

Nota: El hecho de que D0-D9 y NumPad0-NamPad9 sean secuenciales en las claves enum es accidental y confiar en que estos valores se pidan secuencialmente carece de fundamento.

Así solución sería:

  1. determinar si clave dada representa un número.
  2. Devuelve el valor numérico de la tecla si la tecla representa un número.

private static readonly IDictionary<Keys, int> NumericKeys = 
    new Dictionary<Keys, int> { 
     { Keys.D0, 0 }, 
     { Keys.D1, 1 }, 
     { Keys.D2, 2 }, 
     { Keys.D3, 3 }, 
     { Keys.D4, 4 }, 
     { Keys.D5, 5 }, 
     { Keys.D6, 6 }, 
     { Keys.D7, 7 }, 
     { Keys.D8, 8 }, 
     { Keys.D9, 9 }, 
     { Keys.NumPad0, 0 }, 
     { Keys.NumPad1, 1 }, 
     { Keys.NumPad2, 2 }, 
     { Keys.NumPad3, 3 }, 
     { Keys.NumPad4, 4 }, 
     { Keys.NumPad5, 5 }, 
     { Keys.NumPad6, 6 }, 
     { Keys.NumPad7, 7 }, 
     { Keys.NumPad8, 8 }, 
     { Keys.NumPad9, 9 } 
    }; 

private int? GetKeyNumericValue(KeyEventArgs e) { 
    if (NumericKeys.ContainsKey(e.KeyCode)) return NumericKeys[e.KeyCode]; 
    else return null; 
} 

Podría decirse que no es la solución más simple, pero el que los modelos de la solución cuidadosamente.

+0

Hecho esto en un método de extensión. Aquí hay muchas soluciones geniales, pero esta parece ser la más limpia. Gracias. –

+0

Funciona para mí. Gracias. – rajibdotnet

Cuestiones relacionadas