2010-07-01 12 views
8

Attualmente sto gestendo l'evento KeyDown di un controllo DataGridView. Una delle colonne è riempita da valori calcolati e voglio che l'utente sia in grado di sovrascrivere il valore della cella se lo desidera.Evento KeyDown - come sapere facilmente se il tasto premuto è numerico?

Quando l'utente preme un tasto numerico, la cella entra in EditMode e consente all'utente di sovrascrivere il valore. Se la chiave non è numerica, non succede nulla ...

Questo funziona abbastanza bene ... il problema è che trovo il codice brutto ... Non riesco a trovare un modo pulito per gestire tutti i tasti numerici in una sola condizione, così ho fatto un caso interruttore costrutto trattare tutti i possibili tasti numerici, in questo modo:

   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...] 

Certo, funziona, ma ci deve essere una migliore e più breve, giusto?

Tutto quello che potevo trovare con Google è la conversione e.KeyCode ad un char, ma quando si utilizza i tasti numerici, va dà lettere anche per i valori numerici ...

Grazie.

risposta

10

Se si utilizza l'evento KeyPress, la firma dell'evento ha un KeyPressEventArgs con un membro KeyChar che g ti dice il carattere per i tasti del tastierino numerico. Puoi fare un TryParse su quello per capire se è un numero o meno.

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

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

+0

Grazie a Tim e Rawling .Questa è la soluzione con cui sono andato. Devo anche gestire un evento chiave DEL in KeyDown ... Avrei preferito tenere tutto allo stesso livello spot, ma questo codice sembra di gran lunga il più bello. Grazie anche a tutti gli altri. –

1

Sulla msdn help page che usano questo codice in loro esempio:

// 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: grazie, ho pensato a questo, ma io pensavo che fosse una cattiva pratica eseguire valutazioni di intervalli contro le enumerazioni? Sono d'accordo che il fatto che provenga da MSDN lo rende relativamente sicuro, ma dopo tutto, non sarebbe la prima volta che vedremmo codice di esempio errato da MSDN ... C'è qualcosa che garantisce che i valori sarà sempre contiguo? Dopotutto, abbiamo enumerazioni per non fare affidamento sui valori sottostanti? Effettuando tale controllo, non sto facendo affidamento sul fatto che questi valori di enumerazione saranno contigui l'uno con l'altro? Grazie. –

+0

Per quanto possa essere una pratica, spero che, visto che Microsoft lo sta usando nei loro documenti, farebbero attenzione a mantenere il comportamento coerente. Se è possibile passare all'evento KeyPress invece di KeyDown, è possibile utilizzare la soluzione che ho fornito. –

+0

Sì, se c'è un motivo per non farlo, la soluzione di Tim è buona - e rende molto più ovvio ciò che stai cercando di fare anche tu. – Rawling

13

Prova

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

contrassegnato come ans è corretto ma - telerikGrid non supporta KeyPress .. questo funziona ! – 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

Attenzione con questo metodo in quanto non tiene conto dei valori del tastierino numerico (NumPad0 = 96 = 'd') –

6

Perché usare i keycode, quando è possibile utilizzare questo:

void Control_KeyPress(object sender, KeyPressEventArgs e) 
    { 

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

È più pulito e anche se Microsoft decide di cambiare tutte le enumerazioni Vlue, ancora funzionerebbe

4

soluzione Sorcerer86pt è stato il più semplice, tuttavia, quando un utente preme un tasto di controllo, come backspace, quindi si interrompe. Per risolvere questo problema, è possibile utilizzare il seguente frammento:

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 
} 

Se stai usando WPF, si potrebbe trovare che un TextBox non dispone di un evento keyPressed. Per risolvere questo problema, ho usato il seguente codice.

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; 
    } 
} 

Si può notare la funzione di chiamata strana WPFUtils.Interop.Keyboard.GetCharFromKey(e.Key) questa è una delle funzioni utili che ho raccolto. Puoi trovarlo here.

+0

Sì, è meglio così. – Sorcerer86pt

2

Basta prendere l'ultimo carattere dalla chiave che sarà il numero se è stato premuto un numero. Questo metodo funziona con gli eventi KeyDown che non richiedono altre condizioni.

Basta chiamare questo metodo statico e passare la chiave per controllare

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 po 'più versione condensata:

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

proprio come una nota aggiunta, questo non consentirebbe di premere il tasto backspace, insieme a qualsiasi tasto diverso dai numeri. – Takarii

Problemi correlati