Datagridview: ¿Cómo configurar una celda en modo de edición?

Necesito establecer programáticamente una celda en el modo de edición. Sé que establecer esa celda como CurrentCell y luego llamar al método BeginEdit (bool), debería suceder, pero en mi caso, no es así.

Realmente quiero eso, con mi DGV con varias columnas, el usuario SÓLO puede seleccionar y editar los dos primeros. Las otras columnas ya son de solo lectura, pero el usuario puede seleccionarlas, y eso es lo que no quiero.

Así que estaba pensando, decirle al usuario TAB cada vez que ha terminado de escribir en la celda, luego seleccionar la segunda celda, luego tabular de nuevo y seleccionar y comenzar a editar la primera celda de la siguiente fila …

¿Cómo puedo hacer esto?

Configurar el CurrentCell y luego llamar a BeginEdit(true) funciona bien.

El siguiente código muestra un eventHandler para el evento KeyDown que establece que una celda sea editable.

Mi ejemplo solo implementa una de las anulaciones de tecla presionadas requeridas, pero en teoría las demás deberían funcionar de la misma manera. (Y siempre estoy configurando la celda [0] [0] para que sea editable, pero cualquier otra celda debería funcionar)

  private void dataGridView1_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Tab && dataGridView1.CurrentCell.ColumnIndex == 1) { e.Handled = true; DataGridViewCell cell = dataGridView1.Rows[0].Cells[0]; dataGridView1.CurrentCell = cell; dataGridView1.BeginEdit(true); } } 

Si no lo ha encontrado anteriormente, las preguntas frecuentes de DataGridView son un gran recurso, escrito por el administrador del progtwig para el control DataGridView, que cubre la mayor parte de lo que podría querer hacer con el control.

 private void DgvRoomInformation_CellEnter(object sender, DataGridViewCellEventArgs e) { if (DgvRoomInformation.CurrentCell.ColumnIndex == 4) //example-'Column index=4' { DgvRoomInformation.BeginEdit(true); } } 

Bueno, verificaría si alguna de sus columnas está configurada como ReadOnly . Nunca tuve que usar BeginEdit, pero tal vez haya algún uso legítimo. Una vez que haya hecho dataGridView1.Columns[".."].ReadOnly = False; , los campos que no son ReadOnly deben ser editables. Puede usar el evento DataGridView CellEnter para determinar qué celda se ingresó y luego activar la edición en esas celdas después de haber pasado la edición de las dos primeras columnas al siguiente conjunto de columnas y desactivar la edición en las dos últimas columnas.

Sé que esta pregunta es bastante antigua, pero pensé que compartiría un código de demostración con el que esta pregunta me ayudó.

  • Crear un formulario con un Button y un DataGridView
  • Registre un evento Click para button1
  • Registre un evento CellClick para DataGridView1
  • Establezca la propiedad EditMode de EditProgrammatically en EditProgrammatically
  • Pegue el siguiente código en Form1:
 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { DataTable m_dataTable; DataTable table { get { return m_dataTable; } set { m_dataTable = value; } } private const string m_nameCol = "Name"; private const string m_choiceCol = "Choice"; public Form1() { InitializeComponent(); } class Options { public int m_Index { get; set; } public string m_Text { get; set; } } private void button1_Click(object sender, EventArgs e) { table = new DataTable(); table.Columns.Add(m_nameCol); table.Rows.Add(new object[] { "Foo" }); table.Rows.Add(new object[] { "Bob" }); table.Rows.Add(new object[] { "Timn" }); table.Rows.Add(new object[] { "Fred" }); dataGridView1.DataSource = table; if (!dataGridView1.Columns.Contains(m_choiceCol)) { DataGridViewTextBoxColumn txtCol = new DataGridViewTextBoxColumn(); txtCol.Name = m_choiceCol; dataGridView1.Columns.Add(txtCol); } List oList = new List(); oList.Add(new Options() { m_Index = 0, m_Text = "None" }); for (int i = 1; i < 10; i++) { oList.Add(new Options() { m_Index = i, m_Text = "Op" + i }); } for (int i = 0; i < dataGridView1.Rows.Count - 1; i += 2) { DataGridViewComboBoxCell c = new DataGridViewComboBoxCell(); //Setup A c.DataSource = oList; c.Value = oList[0].m_Text; c.ValueMember = "m_Text"; c.DisplayMember = "m_Text"; c.ValueType = typeof(string); ////Setup B //c.DataSource = oList; //c.Value = 0; //c.ValueMember = "m_Index"; //c.DisplayMember = "m_Text"; //c.ValueType = typeof(int); //Result is the same A or B dataGridView1[m_choiceCol, i] = c; } } private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) { if (e.ColumnIndex >= 0 && e.RowIndex >= 0) { if (dataGridView1.CurrentCell.ColumnIndex == dataGridView1.Columns.IndexOf(dataGridView1.Columns[m_choiceCol])) { DataGridViewCell cell = dataGridView1[m_choiceCol, e.RowIndex]; dataGridView1.CurrentCell = cell; dataGridView1.BeginEdit(true); } } } } } 

Tenga en cuenta que los números de índice de la columna pueden cambiar de las pulsaciones de múltiples botones del botón uno, por lo que siempre me refiero a las columnas por nombre y no por valor de índice. Necesitaba incorporar la respuesta de David Hall a mi demo que ya tenía ComboBoxes, por lo que su respuesta funcionó muy bien.

Sé que esta es una pregunta antigua, pero ninguna de las respuestas me funcionó, porque quería establecer de manera confiable (siempre podrá) la celda en el modo de edición cuando posiblemente se ejecuten otros eventos como clics del botón de la barra de herramientas, selecciones de menú, etc. puede afectar el enfoque predeterminado después de que esos eventos regresen. Terminé necesitando un temporizador e invoco. El siguiente código está en un nuevo componente derivado de DataGridView. Este código me permite simplemente hacer una llamada a myXDataGridView.CurrentRow_SelectCellFocus(myDataPropertyName); cada vez que quiero establecer arbitrariamente una celda de datos para editar el modo (suponiendo que la celda no está en el modo ReadOnly).

 // If the DGV does not have Focus prior to a toolbar button Click, // then the toolbar button will have focus after its Click event handler returns. // To reliably set focus to the DGV, we need to time it to happen After event handler procedure returns. private string m_SelectCellFocus_DataPropertyName = ""; private System.Timers.Timer timer_CellFocus = null; public void CurrentRow_SelectCellFocus(string sDataPropertyName) { // This procedure is called by a Toolbar Button's Click Event to select and set focus to a Cell in the DGV's Current Row. m_SelectCellFocus_DataPropertyName = sDataPropertyName; timer_CellFocus = new System.Timers.Timer(10); timer_CellFocus.Elapsed += TimerElapsed_CurrentRowSelectCellFocus; timer_CellFocus.Start(); } void TimerElapsed_CurrentRowSelectCellFocus(object sender, System.Timers.ElapsedEventArgs e) { timer_CellFocus.Stop(); timer_CellFocus.Elapsed -= TimerElapsed_CurrentRowSelectCellFocus; timer_CellFocus.Dispose(); // We have to Invoke the method to avoid raising a threading error this.Invoke((MethodInvoker)delegate { Select_Cell(m_SelectCellFocus_DataPropertyName); }); } private void Select_Cell(string sDataPropertyName) { /// When the Edit Mode is Enabled, set the initial cell to the Description foreach (DataGridViewCell dgvc in this.SelectedCells) { // Clear previously selected cells dgvc.Selected = false; } foreach (DataGridViewCell dgvc in this.CurrentRow.Cells) { // Select the Cell by its DataPropertyName if (dgvc.OwningColumn.DataPropertyName == sDataPropertyName) { this.CurrentCell = dgvc; dgvc.Selected = true; this.Focus(); return; } } }