2010-11-26 18 views
17

El evento de selección de DataGridView no funciona cuando estoy editando texto dentro de una celda.El evento de selección de DataGridView no funciona en C#

voy a asignar acceso directo Alt + S para guardar los datos, funciona cuando la célula no está en modo de edición, pero si está en el modo de edición de abajo código no está funcionando

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

¿No está activado o el código no se ejecutó correctamente? ¿Puedes explicar más sobre lo que estás haciendo? – Rox

+0

partes de algunas respuestas en este enlace están un poco relacionadas- http://stackoverflow.com/questions/686309/datagridview-change-edit-control-size-while-editing/23703744 – barlop

Respuesta

19

Cada vez que una la celda está en modo de edición, su control alojado está recibiendo el evento KeyDown en lugar del padre DataGridView que lo contiene. Es por eso que su método abreviado de teclado funciona cuando una celda no está en modo de edición (incluso si está seleccionada), porque su control DataGridView recibe el evento KeyDown. Sin embargo, cuando se encuentra en el modo de edición, el control de edición que contiene la celda recibe el evento y no sucede nada porque no tiene asociada su rutina de controlador personalizado.

he pasado demasiado tiempo retocando el DataGridView control estándar para manejar editar compromete a la forma que yo quiero, y yo encontrado que la forma más fácil de conseguir alrededor de este fenómeno es como subclase del control existente DataGridView y anulando su ProcessCmdKey function. Cualquier código personalizado que ingrese aquí se ejecutará cada vez que se presione una tecla en la parte superior de DataGridView, independientemente de si está o no en modo de edición.

Por ejemplo, se podría hacer algo como esto:

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

Véase también relacionada, aunque algo mayor, el artículo: How to trap keystrokes in controls by using Visual C#

+0

Buen consejo. La prueba WM_KEYDOWN no ​​es necesaria por cierto. –

+0

Muchas gracias, por su consejo –

+0

@ Hans Passant: Estoy de acuerdo en que no es necesario, y normalmente nunca lo incluyo. Volví a agregarlo después de ver que el artículo que vinculaba lo recomendaba como una "buena práctica". –

13

Otra forma de hacerlo es mediante el evento EditingControlShowing para redirigir la manejo a un controlador de eventos personalizado de la siguiente prueba:

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: Esta es la mejor manera para mí ya que no quiero subclasificar mi DataGridView. – Larry

+0

No estaba claro por qué '- =', que también convirtió a lo anterior VB.net: 'sub privada dgvGrid1_editing (remitente como objeto, e como DataGridViewEditingControlShowingEventArgs) Maneja dgvGrid1.EditingControlShowing si TypeOf e.control es DataGridViewTextBoxEditingControl Entonces Dim tb como DataGridViewTextBoxEditingControl = e.control AddHandler tb.Keydown, AddressOf dgvGrid1_keydown End if End Sub' –

-2

uso PreviewKeyDown caso

private void dataGridView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) 
{ 

} 
+0

Ese evento no se dispara para mí cuando edito una célula –

+0

no funciona para mí tampoco –

3

Una forma más sencilla Sólo traté a cabo es el siguiente:

  1. establecer la propiedad del formulario KeyPreview a true.
  2. En lugar de capturar el evento KeyDown en la cuadrícula, capture el evento KeyDown en el formulario.

Código de la siguiente manera:

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

Gracias. Mucho más fácil :-) –

+0

Muy simple, especialmente porque mi formulario completo es DataGridView. –

1

Ésta es cierto que EditingControlShowing puede ayudar, pero no si se quiere atrapar la tecla Intro. En ese caso, se debe usar el siguiente método:

private void dataGridView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) 
    { 
     if (e.Control is DataGridViewTextBoxEditingControl) 
     { 
      DataGridViewTextBoxEditingControl tb = e.Control as DataGridViewTextBoxEditingControl; 
      tb.KeyDown -= dataGridView_KeyDown; 
      tb.PreviewKeyDown -= dataGridView_PreviewKeyDown; 
      tb.KeyDown += dataGridView_KeyDown; 
      tb.PreviewKeyDown += dataGridView_PreviewKeyDown; 
     } 
    } 

    void dataGridView_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) 
    { 
     if (e.KeyData == Keys.Enter) 
     { 
      <your logic goes here> 
     } 
    } 
Cuestiones relacionadas