2009-08-05 20 views
12

Tenga en cuenta el algoritmo actual a continuación que se repite en las filas de GridView para determinar si el Checkbox contenido está seleccionado/verificado.LINQ: busque todas las casillas marcadas en un GridView

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

Esto funciona como se esperaba: uno se queda con un totalmente poblada List<int>.

Pregunta: ¿Cómo o podría volver a escribir o mejorar este algoritmo usando LINQ para buscar en la GridView para todas las filas que tienen su Checkbox seleccionada/comprobado?

Respuesta

20

estoy bastante seguro de que no va a conseguir ninguna mejora en el rendimiento de esto, pero podría hacerlo ligeramente más fácil de leer:

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

Una vez más, no estoy seguro que hace la diferencia. Además, ¿por qué estás convirtiendo a una cadena y luego a una int? ¿Hay algo que Convert.ToInt32 no pueda hacer por usted?

+0

Thanks LC! 'Convert.ToInt32' debería funcionar bien. ¡Gracias por esa mejora también! –

+0

Esto puede sonar tonto, pero asegúrese de tener 'using System.Linq;' en su lugar antes de tratar de escribir esta declaración. Pude escribir todas las cosas de Linq sin quejarse, sin embargo cuando intenté hacer el reparto implícito (de GridViewRow msgRow) el compilador se quejó de que no había una definición para 'Cast' en GridViewRowCollection y nada en Intelli-sense me dijo que necesitaba un uso – ammills01

9

No estoy seguro de si es IEnumerable filas que no puede ser, pero voy a asumir que son

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>(); 

que acabo de hacer esto en el Bloc de notas, puede haber un error de compilación en ese país. Pero así es como podrías hacer lo mismo con Linq.

+0

Sí, tiene el mismo aspecto que el mío, pero en la sintaxis del método y con un 'ToList' al final (y especificadores de tipo genéricos explícitos). –

+0

Sí, lo vi. Me gusta la sintaxis del método, simplemente se ve más limpio. –

+1

Es un tipo de IEnumerable (a partir de .NET 4.0). Te gustaría hacer 'Rows.OfType () .Where() ...' –

4

Tengo algo similar, pero lo estaba usando en más de un lugar, así que creé un método de extensión.

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

Así que ahora puedo hacer algo con todas las filas marcadas. El compilador es bastante bueno para deducir los tipos, pero ocasionalmente necesito declarar explícitamente checkRows como tipo IEnumerable.

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