2010-01-08 19 views

Respuesta

8

Bueno, descubrí cómo solucionar el problema. En primer lugar, crear una clase llamada CustomDataGridViewTextBoxEditingControl que se deriva de DataGridViewTextBoxEditingControl, y anular EditingControlWantsInputKey así:

public override bool EditingControlWantsInputKey(
    Keys keyData, 
    bool dataGridViewWantsInputKey) 
{ 
    switch (keyData & Keys.KeyCode) 
    { 
     case Keys.Enter: 
      // Don't let the DataGridView handle the Enter key. 
      return true; 
     default: 
      break; 
    } 

    return base.EditingControlWantsInputKey(keyData, dataGridViewWantsInputKey); 
} 

Esto detiene el DataGridView de entregar la tecla Intro y el cambio de la celda actual. Sin embargo, no hace que la tecla Enter agregue una nueva línea. (Parece que el DataGridViewTextBoxEditingControl ha eliminado la funcionalidad de la tecla Intro). Por lo tanto, tenemos que sobreescribir OnKeyDown e implementar la funcionalidad de nosotros mismos, de esta manera:

protected override void OnKeyDown(KeyEventArgs e) 
{ 
    switch (e.KeyCode & Keys.KeyCode) 
    { 
     case Keys.Enter: 
      int oldSelectionStart = this.SelectionStart; 
      string currentText = this.Text; 

      this.Text = String.Format("{0}{1}{2}", 
       currentText.Substring(0, this.SelectionStart), 
       Environment.NewLine, 
       currentText.Substring(this.SelectionStart + this.SelectionLength)); 

      this.SelectionStart = oldSelectionStart + Environment.NewLine.Length; 
      break; 
     default: 
      break; 
    } 

    base.OnKeyDown(e); 
} 

A continuación, cree una clase llamada CustomDataGridViewTextBoxCell que se deriva de DataGridViewTextBoxCell, y reemplazar la propiedad EditType para devolver el tipo de CustomDataGridViewTextBoxEditingControl.

public override Type EditType 
{ 
    get 
    { 
     return typeof(CustomDataGridViewTextBoxEditingControl); 
    } 
} 

Después de hacer esto, se puede establecer la propiedad CellTemplate en una columna existente a un CustomDataGridViewTextBoxCell, o puede crear una clase derivada de DataGridViewColumn con CellTemplate preestablecido a un CustomDataGridViewTextBoxCell, y usted estará listo!

+0

Hay, me gusta esta solución. Me ha funcionado, pero falta una cosa. ¿Cómo puedo aumentar la altura de fila de todas las celdas que están en la misma fila que este cuadro de texto de vista de cuadrícula de datos? ¿Es posible?. Obviamente, esto también debería ocurrir al presionar la tecla enter. –

+0

Disculpas, el problema que estaba teniendo estaba causado por mi propiedad de modo de filas de autosize que se establece en todas las celdas. Me.EditingControlDataGridView.Rows (EditingControlRowIndex) .Height + = 10 trabajado un encanto –

5

Puede hacerlo estableciendo la propiedad DataGridViewCellStyle.WrapMode en verdadero. De MSDN:

Si WrapMode es falsa para una celda que contiene el texto , la celda muestra el texto en una sola línea, y muestra cualquier carácter de nueva línea embebidos como caja caracteres. Si WrapMode es True para una celda que contiene texto, la celda muestra caracteres de nueva línea como línea , pero también ajusta las líneas que exceden el ancho de la celda.

Puede configurar esto para celdas específicas accediendo a la propiedad Style en una celda, o para todas las celdas en una columna usando DefaultCellStyle para la columna.

[Actualización] Para desactivar la tecla Intro selectivamente en su DataGridView, agregue un filtro de mensajes al formulario que contiene el DataGridView como se muestra a continuación:

private KeyMessageFilter m_filter = null; 

private void Form1_Load(object sender, EventArgs e) 
{ 
    m_filter = new KeyMessageFilter(this); 
    Application.AddMessageFilter(m_filter); 

} 

Aquí es la clase de filtro de mensajes:

public class KeyMessageFilter : IMessageFilter 
{ 
    private Form m_target = null; 

    public KeyMessageFilter(Form targetForm) 
    { 
     m_target = targetForm; 
    } 

    private const int WM_KEYDOWN = 0x0100; 

    private const int WM_KEYUP = 0x0101; 


    public bool PreFilterMessage(ref Message m) 
    { 
     if (m.Msg == WM_KEYDOWN) 
     { 
      //Note this ensures Enter is only filtered if in the 
      // DataGridViewTextBoxEditingControl and Shift is not also pressed. 
      if (m_target.ActiveControl != null && 
       m_target.ActiveControl is DataGridViewTextBoxEditingControl && 
       (Keys)m.WParam == Keys.Enter && 
       (Control.ModifierKeys & Keys.Shift) != Keys.Shift) 
      { 
       return true; 
      } 

     } 

     return false; 
    } 
} 

Ahora, la tecla Intro está desactivada al editar texto y debe presionar la tecla de tabulación para pasar a la celda siguiente. Shift + Enter aún agrega una nueva línea al texto que está editando.

Espero que esto ayude.

+0

Gracias! Su respuesta solucionó el problema de permitir varias líneas en la celda, pero desafortunadamente la tecla Intro aún cambia la celda seleccionada. –

+0

@Zach, mira mi actualización y muestra el código anterior. – Ash

+0

Para aclararlo, si WrapMode se establece en True, la tecla Intro se moverá a la siguiente fila, pero ahora puede usar Mayús + Entrar para insertar una nueva línea en el texto. Si está contento con ese comportamiento, el filtro de mensaje no es obligatorio. – JonP

Cuestiones relacionadas