LINQ: trova tutte spuntato le caselle in una GridView

Prendere in considerazione l’attuale algoritmo di sotto che scorre da un GridView‘s righe per trovare se il contenuto Checkbox è selezionato/controllati.

List<int> checkedIDs = new List<int>();

foreach (GridViewRow msgRow in messagesGrid.Rows)
{
  CheckBox chk = (CheckBox)msgRow.FindControl("chkUpdateStatus");
  if (chk.Checked){
   //we want the GridViewRow's DataKey value
   checkedMsgIDs.Add(int.Parse(messagesGrid.DataKeys[msgRow.RowIndex].Value.ToString()));
  }
}

Questo funziona come previsto: si è lasciato con una cucina completamente popolato List<int>.

Domanda: Come sarebbe o potrebbe ri-scrivere o migliorare questo algoritmo utilizzando LINQ per la ricerca di GridView per tutte le righe che hanno il loro Checkbox selezionato/controllato?

InformationsquelleAutor p.campbell | 2009-08-05



3 Replies
  1. 20

    Sono abbastanza sicuro che non hai intenzione di ottenere un miglioramento delle prestazioni, ma potrebbe rendere leggermente più facile da leggere:

    var checkedIDs = from GridViewRow msgRow in messagesGrid.Rows
                     where ((CheckBox)msgRow.FindControl("chkUpdateStatus")).Checked
                     select Int32.Parse(messagesGrid.DataKeys[msgRow.RowIndex].Value.ToString());

    Di nuovo, non di certo fa la differenza. Inoltre, perché è la conversione di una stringa in un int? C’è qualcosa di Convert.ToInt32 non può fare per voi?

    • Grazie LC! Convert.ToInt32 dovrebbe funzionare bene. Grazie per il miglioramento!
    • Questo potrebbe sembrare stupido, ma assicurarsi che si ha utilizzando il Sistema di.Linq;’ prima di provare a scrivere questa dichiarazione. Sono stato in grado di scrivere tutti i Linq cose senza lamentarsi, però quando ho provato a fare il cast implicito (da GridViewRow msgRow) il compilatore si è lamentato di non avere una definizione di “Cast” in GridViewRowCollection e nulla in Intelli-sense mi ha detto che avevo bisogno di un tramite.
  2. 9

    Io non sono sicuro se il numero di Righe è IEnumerable potrebbero non essere, ma ho intenzione di assumere che sono

    List<int> checkedIDs = messagesGrid.Rows
      .Where<GridViewRow>(i => (CheckBox)i.FindControl("chkUpdateStatus").Checked)
      .Select<GridViewRow, int>(i => return int.Parse(messagesGrid.DataKeys[i.RowIndex].Value.ToString()))
      .ToList<int>();

    Ho appena fatto questo nel blocco note, ci potrebbe essere un errore di compilazione in là. Ma questo è come si potrebbe fare la stessa cosa con Linq.

    • Sì, sembra uguale al mio, ma la sintassi del metodo e con un ToList alla fine (ed esplicita di tipo generico identificatori).
    • Sì, ho visto che. Mi piace la sintassi del metodo mi sembra più pulito.
    • È priva di tipo IEnumerable (come di .NET 4.0). Si vuole fare Rows.OfType<GridViewRow>().Where()...
  3. 4

    Ho qualcosa di simile, ma io l’ho usato in più di un luogo così ho creato un metodo di estensione.

    public static void ActOnCheckedRows(this GridView gridView, string checkBoxId, Action<IEnumerable<int>> action)
    {
       var checkedRows = from GridViewRow msgRow in gridView.Rows
                         where ((CheckBox)msgRow.FindControl(checkBoxId)).Checked
                         select (int) gridView.DataKeys[msgRow.RowIndex].Value;
    
        action(checkedRows);
    }

    Così ora posso fare qualcosa con tutto il bagaglio di righe. Il compilatore è abbastanza bravo a dedurre i tipi ma di tanto in tanto ho bisogno di dichiarare in modo esplicito checkedRows tipo IEnumerable.

    gvTasksToBill.ActOnCheckedRows("RowLevelCheckBox", checkedRows =>
    {
        foreach (int id in checkedRows)
        {
           //do something with id
        }
    });

Lascia un commento