2008-11-28 4 views
7

Ich brauche die Tasten drücken Ereignisse während der Bearbeitung der Zelle in DataGridView Kontrolle.So erhalten Sie keypressed, Keydown-Ereignisse von DataGridView-Datenzellen

Von dem, was ich im Netz gefunden habe, ist die DataGridView entwickelt, um alle wichtigen Ereignisse von DataGridView an die Zelle Bearbeitungssteuerung übergeben und Sie können diese Ereignisse nicht leicht erhalten.

Ich fand diese piece of code, die diese Ereignisse für Steuerelement erfasst, aber das funktioniert nicht für DataGridView.

Antwort

2

Endlich herausgefunden. Es gibt zwei Teile dieses Puzzles - Schlüssel aus der Bearbeitung von Zellen abrufen und Schlüssel aus dem DataGridView selbst erhalten. Hier ist mein Code. Um es zu verwenden, müssen Sie nur das benutzerdefinierte Ereignis abonnieren: keyPressHook.

class KeyPressAwareDataGridView : DataGridView 
{ 

    protected override void OnControlAdded(ControlEventArgs e) 
    { 
     this.subscribeEvents(e.Control); 
     base.OnControlAdded(e); 
    } 

    protected override void OnControlRemoved(ControlEventArgs e) 
    { 
     this.unsubscribeEvents(e.Control); 
     base.OnControlRemoved(e); 
    } 

    protected override bool ProcessDataGridViewKey(KeyEventArgs e) 
    { 
     bool procesedInternally = false; 

     if (this.keyPressHook != null) 
     { 
      this.keyPressHook(this, e); 
      procesedInternally = e.SuppressKeyPress; 
     } 

     if (procesedInternally) 
     { 
      return true; 
     } 
     else 
     { 
      return base.ProcessDataGridViewKey(e); 
     } 
    } 


    private void subscribeEvents(Control control) 
    { 
     control.KeyDown += new KeyEventHandler(this.control_KeyDown); 
     control.ControlAdded += new ControlEventHandler(this.control_ControlAdded); 
     control.ControlRemoved += new ControlEventHandler(this.control_ControlRemoved); 

     foreach (Control innerControl in control.Controls) 
     { 
      this.subscribeEvents(innerControl); 
     } 
    } 

    private void unsubscribeEvents(Control control) 
    { 
     control.KeyDown -= new KeyEventHandler(this.control_KeyDown); 
     control.ControlAdded -= new ControlEventHandler(this.control_ControlAdded); 
     control.ControlRemoved -= new ControlEventHandler(this.control_ControlRemoved); 

     foreach (Control innerControl in control.Controls) 
     { 
      this.unsubscribeEvents(innerControl); 
     } 
    } 

    private void control_ControlAdded(object sender, ControlEventArgs e) 
    { 
     this.subscribeEvents(e.Control); 
    } 

    private void control_ControlRemoved(object sender, ControlEventArgs e) 
    { 
     this.unsubscribeEvents(e.Control); 
    } 

    private void control_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (this.keyPressHook != null) 
     { 
      this.keyPressHook(this, e); 
     } 
    } 

    public event KeyEventHandler keyPressHook; 

} 
+0

Können Sie weitere Informationen dazu liefern? – eladyanai

0

Sie müssen die DataGridViewCell/DataGridViewTextBoxCell/otherTypes überschreiben und Schlüssel * Ereignisse in der abgeleiteten Klasse behandeln.

1

Vielleicht nicht so nett wie Mladen Prajdics Antwort oben, aber vielleicht ein wenig einfacher, je nach Ihrer Situation. Sie können die ProcessCmdKey-Methode des Formulars oder des Steuerelements selbst überschreiben, Tastenanschläge dort verarbeiten und nach der aktuellen Zelle suchen.

2

Try this:

class KeyPressAwareDataGridView : DataGridView 
{ 
    protected override void OnControlAdded(ControlEventArgs e) 
    { 
     SubscribeEvents(e.Control); 
     base.OnControlAdded(e); 
    } 

    protected override void OnControlRemoved(ControlEventArgs e) 
    { 
     UnsubscribeEvents(e.Control); 
     base.OnControlRemoved(e); 
    } 

    private void SubscribeEvents(Control control) 
    { 
     control.KeyPress += new KeyPressEventHandler(control_KeyPress); 
     control.ControlAdded += new ControlEventHandler(control_ControlAdded); 
     control.ControlRemoved += new ControlEventHandler(control_ControlRemoved); 

     foreach (Control innerControl in control.Controls) 
     { 
      SubscribeEvents(innerControl); 
     } 
    } 

    private void UnsubscribeEvents(Control control) 
    { 
     control.KeyPress -= new KeyPressEventHandler(control_KeyPress); 
     control.ControlAdded -= new ControlEventHandler(control_ControlAdded); 
     control.ControlRemoved -= new ControlEventHandler(control_ControlRemoved); 

     foreach (Control innerControl in control.Controls) 
     { 
      UnsubscribeEvents(innerControl); 
     } 
    } 

    private void control_ControlAdded(object sender, ControlEventArgs e) 
    { 
     SubscribeEvents(e.Control); 
    } 

    private void control_ControlRemoved(object sender, ControlEventArgs e) 
    { 
     UnsubscribeEvents(e.Control); 
    } 

    private void control_KeyPress(object sender, KeyPressEventArgs e) 
    { 
     // Apply your logic here whether this is the key pressed event you need. 
     // (e.g. "if(SelectedCells != null)") 
     MessageBox.Show(e.KeyChar.ToString()); 
    } 
} 
0

fand ich eine Teillösung durch zu EditingControlShowing Hören und das Hinzufügen von Schlüssel Zuhörer zu jedem neuen Editiersteuerabschnitt.

Dies gibt mir Zugriff auf die meisten Tasten, aber ich bekomme immer noch keine Pfeiltasten.

Ich werde versuchen, was Eren Aygunes vorgeschlagen.

2

Oder für diejenigen, die nicht wollen, unsere eigenen DataGridView für solche Gelegenheiten zu erstellen; Es gibt diese Methode (in C++): Sie verwendet das EditingControlShowing Event der DataGridView.

private: System::Boolean fIsNonNumeric; 
private: static System::Windows::Forms::KeyEventHandler^ EventKeyDown = nullptr; 
private: static System::Windows::Forms::KeyPressEventHandler^ EventKeyPress = nullptr; 
private: System::Void dataGridView_KeyDown(System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) 
{ 
    fIsNonNumeric= false; 

    // 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) 
    { 
     // Determine whether the keystroke is a backspace. 
     if (e->KeyCode != Keys::Back) 
     { 
     // A non-numerical keystroke was pressed. 
     // Set the flag to true and evaluate in KeyPress event. 
     fIsNonNumeric = true; 
     } 
    } 
    } 
} 

private: System::Void dataGridView_KeyPress(System::Object^ sender, System::Windows::Forms::KeyPressEventArgs^ e) 
{ 
    // Should we stop the character from being entered...? 
    if (fIsNonNumeric == true) 
    e->Handled = true; 
} 

private: System::Void dataGridView_Machines_EditingControlShowing(System::Object^ sender, System::Windows::Forms::DataGridViewEditingControlShowingEventArgs^ e) 
{ 
    if (nullptr == EventKeyDown) 
    EventKeyDown = (gcnew System::Windows::Forms::KeyEventHandler(this, &ProjectForm::dataGridView_KeyDown)); 

    if (nullptr == EventKeyPress) 
    EventKeyPress = (gcnew System::Windows::Forms::KeyPressEventHandler(this, &ProjectForm::dataGridView_KeyPress)); 

    e->Control->KeyDown -= EventKeyDown; 
    e->Control->KeyPress -= EventKeyPress; 

    e->Control->KeyDown += EventKeyDown; 
    e->Control->KeyPress += EventKeyPress; 
}