El evento de selección de DataGridView no funciona en C #

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

Estoy asignando el atajo Alt + S para guardar los datos, funciona cuando la celda no está en modo de edición, pero si está en el modo de edición a continuación el código no funciona

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

Cada vez que una celda se encuentra en modo de edición, su control alojado recibe el evento KeyDown 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 control DataGridView estándar para manejar las confirmaciones de edición de la manera que quiero, y encontré que la forma más sencilla de evitar este fenómeno es subclasificando el control DataGridView existente y anulando su función ProcessCmdKey . 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, podrías 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); } } 

Vea también un artículo relacionado, aunque algo más antiguo: Cómo atrapar las pulsaciones de teclas en los controles mediante el uso de Visual C #

Otra forma de hacerlo es mediante el uso del evento EditingControlShowing para redirigir el manejo del evento a un controlador de eventos personalizado como se muestra a continuación:

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

Una forma más simple que acabo de probar es la siguiente:

  1. Establezca la propiedad KeyPreview del formulario en true .
  2. En lugar de capturar el evento KeyDown en Grid, capture el evento KeyDown en Form.

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 

Esto es cierto que EditingControlShowing puede ayudar, pero no si quiere capturar la tecla Enter. En ese caso, uno 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) {  } } 

usar el evento PreviewKeyDown

 private void dataGridView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { }