2008-11-28 65 views
7

Necesito recibir los eventos de pulsación de teclas durante la edición de celda en el control DataGridView.Cómo obtener eventos keydown, keydown de las celdas de datos DataGridView

Por lo que he encontrado en la red del DataGridView diseñada para pasar todos los eventos clave de DataGridView al control de edición de celdas y no se puede conseguir fácilmente estos eventos.

Encontré este piece of code que atrapa esos eventos para el control DataGrid, pero eso no funciona para DataGridView.

Respuesta

2

Finalmente resuelto. Hay dos partes de este rompecabezas: obtener claves del control de edición de celda y obtener claves del DataGridView. Aquí está mi código. Para usarlo, solo necesita suscribirse al evento personalizado: 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

¿Puede proporcionar más información sobre cómo hacerlo? – eladyanai

0

tiene que anular DataGridViewCell/DataGridViewTextBoxCell/otherTypes y manejar key * events en la clase derivada.

1

Quizás no sea tan agradable como la respuesta de Mladen Prajdic anterior, pero tal vez un poco más fácil, dependiendo de su situación. Puede anular el método ProcessCmdKey del formulario o el control en sí, manejar las pulsaciones de teclado allí y comprobar la celda actual.

2

Prueba esto:

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

he encontrado una solución parcial al escuchar EditingControlShowing y añadiendo detector de teclas para cada nuevo control de edición.

Esto me da acceso a la mayoría de las teclas, pero sigo sin obtener las teclas de flecha.

Voy a probar lo que sugirió Eren Aygunes.

2

O, para aquellos de uso que NO desean crear nuestro propio DataGridView para tales ocasiones; existe este método (en C++): utiliza el evento EditingControlShowing del 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; 
} 
Cuestiones relacionadas