2010-11-26 16 views
17

Das DataGridView-Keydown-Ereignis funktioniert nicht, wenn ich Text in einer Zelle bearbeite.DataGridView-Keydown-Ereignis funktioniert nicht in C#

Ich Zuweisung Verknüpfung Alt + S die Daten zu speichern, funktioniert es, wenn die Zelle nicht im Bearbeitungsmodus befindet, aber wenn es im Bearbeitungsmodus unter Code funktioniert nicht

private void dataGridView1_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.KeyData == (Keys.Alt | Keys.S)) 
    { 
     //save data 
    } 
} 
+0

Es ist nicht gefeuert, oder der Code wird nicht korrekt ausgeführt? Können Sie mehr über das, was Sie tun, erklären? – Rox

+0

Teile von einigen Antworten auf diesen Link sind ein bisschen verwandt- http://StackOverflow.com/Questions/686309/Datagridview-change-Edit-Control-Size-while-Editing/23703744 – barlop

Antwort

19

Jedes Mal, wenn ein Zelle befindet sich im Bearbeitungsmodus, das gehostete Steuerelement empfängt das KeyDown Ereignis anstelle des übergeordneten Elements DataGridView, das es enthält. Deshalb funktioniert Ihr Tastaturkürzel immer dann, wenn sich eine Zelle nicht im Bearbeitungsmodus befindet (selbst wenn sie ausgewählt ist), weil Ihr Steuerelement DataGridView das Ereignis KeyDown empfängt. Wenn Sie sich jedoch in Bearbeitungsmodus befinden, empfängt das Bearbeitungssteuerelement, das von der Zelle enthalten wird, das Ereignis, und nichts geschieht, da es Ihre benutzerdefinierte Handler-Routine nicht verknüpft hat.

Ich habe viel zu viel Zeit damit verbracht, den Standard DataGridView Steuer zwicken, wie ich es will behandeln bearbeiten verpflichtet, und ich fand, dass der einfachste Weg, um dieses Phänomen zu bekommen, ist durch die bestehende DataGridView Steuer Subklassen und seine zwingenden ProcessCmdKey function. Welcher benutzerdefinierte Code hier eingegeben wird, wird ausgeführt, wenn eine Taste oben auf DataGridView gedrückt wird, unabhängig davon, ob sie sich im Bearbeitungsmodus befindet oder nicht.

Zum Beispiel, können Sie so etwas tun könnten:

class MyDataGridView : System.Windows.Forms.DataGridView 
{ 
    protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) 
    { 

     MessageBox.Show("Key Press Detected"); 

     if ((keyData == (Keys.Alt | Keys.S))) 
     { 
      //Save data 
     } 

     return base.ProcessCmdKey(ref msg, keyData); 
    } 
} 

Siehe auch im Zusammenhang, wenn auch schon etwas älter, Artikel: How to trap keystrokes in controls by using Visual C#

+0

Guter Rat. Der WM_KEYDOWN-Test ist zwischenzeitlich nicht notwendig. –

+0

Vielen Dank, für Ihren Ratschlag –

+0

@Hans Passant: Ich stimme zu, dass es nicht notwendig ist, und normalerweise schließe ich es nie ein. Ich ging zurück, um es hinzuzufügen, nachdem ich gesehen habe, dass der Artikel, den ich verlinkte, es als "gute Praxis" empfahl. –

13

Ein anderer Weg, es zu tun ist durch das EditingControlShowing Ereignis mit der Umleitung Event Handler benutzerdefinierte Ereignisbehandlung wie folgt:

private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) 
{ 
    if (e.Control is DataGridViewTextBoxEditingControl tb) 
      { 
       tb.KeyDown -= dataGridView1_KeyDown; 
       tb.KeyDown += dataGridView1_KeyDown; 
      } 
} 

//then in your keydown event handler, execute your code 
private void dataGridView1_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.KeyData == (Keys.Alt | Keys.S)) 
    { 
     //save data 
    } 
} 
+2

+1: Dies ist der beste Weg für mich, da ich mein DataGridView nicht ableiten möchte. – Larry

+0

war ich nicht klar, warum ‚- =‘, ich konvertiert auch die oben VB.net: 'Privatunter dgvGrid1_editing (Absender als Gegenstand, e als DataGridViewEditingControlShowingEventArgs) Griffe dgvGrid1.EditingControlShowing wenn TypeOf e.control DataGridViewTextBoxEditingControl Dann ist dim tb als DataGridViewTextBoxEditingControl = e.control AddHandler tb.Keydown, AddressOf dgvGrid1_keydown End if End Sub' –

-2

Verwendung PreviewKeyDown Ereignis

private void dataGridView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) 
{ 

} 
+0

Das Ereignis für mich nicht feuern, wenn ich eine Zelle bearbeiten –

+0

hat bei mir nicht funktioniert entweder –

3

Eine einfachere Weise, die ich gerade ausprobiert wie folgt:

  1. Stellen Sie die KeyPreview-Eigenschaft des Formulars zu true.
  2. Anstatt das KeyDown-Ereignis in Grid abzufangen, fangen Sie das KeyDown-Ereignis in Form ab.

-Code wie folgt:

Private Sub form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown 

    If grd.Focused Then 

     'Do your work 

    End If 

End Sub 
+0

Danke. Viel einfacher :-) –

+0

Sehr einfach, vor allem als meine gesamte Form ist das DataGridView. –

1

Dies ist wahr, dass EditingControlShowing helfen können, aber nicht, wenn Sie die Enter-Taste fangen will. In diesem Fall sollte man die folgende Methode verwenden: