2009-08-05 14 views
12

Rozważmy aktualny algorytm poniżej że iteracje przez GridView „s wierszy znaleźć, czy zawarte Checkbox wybrano/sprawdzane.LINQ: Znajdź wszystkie zaznaczone pola wyboru w 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())); 
    } 
} 

Działa to zgodnie z oczekiwaniami: pozostało Ci całkowicie wypełnione List<int>.

Pytanie: W jaki sposób można lub ponownego zapisu lub poprawić ten algorytm przy użyciu LINQ przeszukać GridView dla wszystkich wierszy, które mają swoje Checkbox wybrany/sprawdzane?

Odpowiedz

20

Jestem całkiem pewien, że nie dostaniesz żadnej poprawy wydajności od tego, ale może to zrobić nieznacznie łatwiejsze do odczytania:

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

Ponownie, nie jestem pewien, to robi różnicę. Ponadto, dlaczego konwertujesz na ciąg, a następnie na int? Czy jest coś, czego nie może dla ciebie zrobić Convert.ToInt32?

+0

Dzięki LC! 'Convert.ToInt32' powinno działać poprawnie. Dzięki za to ulepszenie! –

+0

Może to zabrzmieć głupio, ale upewnij się, że używasz "System.Linq;" na miejscu, zanim spróbujesz napisać to stwierdzenie. Udało mi się napisać wszystkie rzeczy Linq bez niego skarży jednak gdy próbowałem zrobić niejawny obsady (od GridViewRow msgRow) kompilator narzekali nie ma definicji dla „Obsada” w GridViewRowCollection i nic w Intelli-sensie mi że potrzebowałem użycia. – ammills01

9

Nie jestem pewien, czy jest IEnumerable Wiersze nie mogą być, ale mam zamiar założyć, że są

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

I właśnie to zrobił w notatniku, nie może być błąd kompilacji tam. Ale w ten sposób możesz zrobić to samo z Linq.

+0

Tak, wygląda tak samo jak ja, ale w składni metody iz 'ToList' na końcu (i jednoznacznych ogólnych specyfikatorami typ). –

+0

Tak, widziałem to. Podobała mi się składnia metody, która wygląda na czystszą. –

+1

To nienumerowana IEnumerable (od .NET 4.0). Chciałbyś zrobić 'Rows.OfType () .Where() ...' –

4

mam coś podobnego, ale używałem go w więcej niż jednym miejscu, więc stworzyłem metodę rozszerzenia.

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

Teraz mogę zrobić coś ze wszystkimi zaznaczonymi wierszami. Kompilator jest dość dobry w dedukowaniu typów, ale czasami muszę jawnie zadeklarować checkRows jako typ IEnumerable.

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