2014-10-23 16 views
5

Ho una funzione chiamata da cell_endit. Si muove un DataGridViewRow all'interno di un dataGridView:Come evitare la chiamata di rientro a setCurrentCellAddressCore?

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

alla riga table.Rows.Insert (NewIndex, 1) ottengo il seguente errore:

Unhandled exception of type "System.InvalidOperationException" in System.Windows.Forms.dll

Additional data: Operation is not valid because it results in a reentrant call to the SetCurrentCellAddressCore function.

Succede quando si sceglie un'altra cella in fase di modifica della cella corrente. Come posso evitare questo errore e inserire correttamente la mia riga?

risposta

15

Questo errore è causato da

Any operation that results in the active cell being changed while the DataGridView is still using it

come la risposta accettata in this post.

La correzione (ho verificato): utilizzare BeginInvoke per chiamare moveRowTo.

private void dataGridView2_CellEndEdit(object sender, DataGridViewCellEventArgs e) 
{ 
    this.BeginInvoke(new MethodInvoker(() => 
     { 
      moveRowTo(dataGridView2, 0, 1); 
     })); 
} 

BeginInvoke è una chiamata asincrona, quindi dataGridView2_CellEndEdit ritorna immediatamente, e il metodo moveRowTo viene eseguita dopo che, in quel momento dataGridView2 non utilizza la cella attualmente attiva.

-1
if (
    (datagridview.SelectedCells[0].RowIndex != datagridview.CurrentCell.RowIndex) || 
    (datagridview.SelectedCells[0].ColumnIndex!= datagridview.CurrentCell.ColumnIndex) 
    ) { return; } 
+1

Mentre questo codice può rispondere alla domanda, fornire un contesto aggiuntivo su come e/o perché risolve il problema migliorerebbe il valore a lungo termine della risposta. –