2012-12-25 19 views
6

Ho un WPF DataGrid theDataGrid associato a DataSet ds contenente una tabella. Voglio consentire all'utente di rimuovere le righe selezionandole prima nella griglia e premendo un pulsante (posizionato al di fuori del datagrid). Ho finalmente arrivati ​​alle seguenti righe di codice che faccio quello che voglio, ma che considero piuttosto brutto:Rimozione di righe da un datagrid WPF

DataSet ds = new DataSet(); 
     ... 
    // fill ds somehow 
     ... 
    private void ButtonClickHandler(object Sender, RoutedEventArgs e) 
    { 
     List<DataRow> theRows = new List<DataRow>(); 
     for (int i = 0; i < theDataGrid.SelectedItems.Count; ++i) 
     { 
      // o is only introduced to be able to inspect it during debugging 
      Object o = theDataGrid.SelectedItems[i]; 
      if (o != CollectionView.NewItemPlaceholder) 
      { 
       DataRowView r = (DataRowView)o; 
       theRows.Add(r.Row); 
      } 
     } 
     foreach(DataRow r in theRows) 
     {     
      int k = ds.Tables["producer"].Rows.IndexOf(r); 
      // don't remove() but delete() cause of update later on 
      ds.Tables[0].Rows[k].Delete(); 
     } 
    } 

Esiste un modo migliore per fare questo? Per esempio. uno che ha bisogno di un solo ciclo e senza dover verificare esplicitamente lo NewItemPlaceHolder o un modo più efficiente per accedere alle righe che devono essere cancellate?

(ho già capito che non devo togliere nulla dal DS nel primo ciclo, da allora theDataGrid.SelectedItems.Count modifiche ogni volta che il ciclo viene eseguito ...)

+0

ho una soluzione vuoi che la aggiungo ?? – gasroot

risposta

0

penso che funziona per un solo ciclo:

int count=theDataGrid.SelectedItems.Count; 
int removedCount=0; 
while (removedCount < count) 
{ 
    try{ 
     Object o = theDataGrid.SelectedItems[0]; 
    } 
    catch{ break;} 

    if (o == CollectionView.NewItemPlaceholder) 
    continue; 

    DataRowView r = (DataRowView)o; 
    r.Row.Delete(); 
    removedCount++; 
} 
+0

Uhmm, grazie ma no. Il ciclo foreach che hai aggiunto dopo "Modifica" è stata la mia prima "soluzione", in realtà. Risulta un'eccezione non gestita. Questo è ciò a cui mi riferivo nell'ultima riga della mia domanda, quella tra parentesi. La collezione SelectedItems cambia durante il ciclo e il contatore foreach si riferisce a qualcosa di non valido (credo). Mi aspetterei lo stesso con il primo approccio. – Thomas

+0

@Thomas Hai ragione sul secondo, ma almeno sono sicuro che 'Collection Modified Exception' non verrà lanciato nel primo. – Ramin

+0

Arresta in modo anomalo perché si aumenta l'indice che alla fine diventa più grande del (corrente) SelectedItems.Count. Probabilmente funzionerà se recuperi SelectedIndex [0] ogni volta. Ma, ad essere onesti, con un contatore aggiornato manualmente non è più bello del mio codice. Quello che mi piacerebbe avere è un solo liner come il tuo secondo suggerimento, ma uno che non si blocca ;-) – Thomas

0

È possibile rimuovere il doppio loop mediante iterazione all'indietro:

private void ButtonClickHandler(object Sender, RoutedEventArgs e) { 
    for (int i = theDataGrid.SelectedItems.Count-1; i>=0; --i) 
     if (theDataGrid.SelectedItems[i] != CollectionView.NewItemPlaceholder) 
      ds.Tables[0].Rows[i].Delete(); 
    } 
1

al fine di rimuovere riga selezionata sul fare clic sul pulsante si può provare:

private void ButtonClickHandler(object sender, RoutedEventArgs e)//Remove row selected 
    { 
     DataRowView dataRow = (DataRowView)dataGridCodes.SelectedItem; //dataRow holds the selection 
     dataRow.Delete();      
    }