c# - ¿Cómo evadir la llamada de reentrada a setCurrentCellAddressCore?
datagridview invalidoperationexception (2)
Tengo una función que se llama desde cell_endedit. Mueve un dataGridViewRow dentro de un dataGridView:
private void moveRowTo(DataGridView table, int oldIndex, int newIndex)
{
if (newIndex < oldIndex)
{
oldIndex += 1;
}
else if (newIndex == oldIndex)
{
return;
}
table.Rows.Insert(newIndex, 1);
DataGridViewRow row = table.Rows[newIndex];
DataGridViewCell cell0 = table.Rows[oldIndex].Cells[0];
DataGridViewCell cell1 = table.Rows[oldIndex].Cells[1];
row.Cells[0].Value = cell0.Value;
row.Cells[1].Value = cell1.Value;
table.Rows[oldIndex].Visible = false;
table.Rows.RemoveAt(oldIndex);
table.Rows[oldIndex].Selected = false;
table.Rows[newIndex].Selected = true;
}
en row table.Rows.Insert (newIndex, 1) me sale el siguiente error:
Excepción no controlada del tipo "System.InvalidOperationException" en System.Windows.Forms.dll
Datos adicionales: la operación no es válida porque da como resultado una llamada de reentrada a la función SetCurrentCellAddressCore.
Sucede cuando hago clic en otra celda en proceso de edición de la celda actual. ¿Cómo puedo evadir ese error y hacer que mi fila se inserte correctamente?
Este error es causado por
Cualquier operación que dé como resultado que la celda activa se modifique mientras DataGridView todavía la está usando
Como la respuesta aceptada en esta publicación .
La solución (he verificado): use BeginInvoke
para llamar a moveRowTo
.
private void dataGridView2_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
this.BeginInvoke(new MethodInvoker(() =>
{
moveRowTo(dataGridView2, 0, 1);
}));
}
BeginInvoke
es una llamada asincrónica, por lo que dataGridView2_CellEndEdit
devuelve inmediatamente, y el método moveRowTo
se ejecuta después de eso, en ese momento dataGridView2
ya no está utilizando la celda actualmente activa.
if (
(datagridview.SelectedCells[0].RowIndex != datagridview.CurrentCell.RowIndex) ||
(datagridview.SelectedCells[0].ColumnIndex!= datagridview.CurrentCell.ColumnIndex)
) { return; }