Подтвердить что ты не робот

LINQ: найти все отмеченные флажки в GridView

Рассмотрим текущий алгоритм ниже, который выполняет итерацию через строки GridView, чтобы определить, выбрано/отмечено ли содержащееся Checkbox.

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 DataKey value
   checkedMsgIDs.Add(int.Parse(messagesGrid.DataKeys[msgRow.RowIndex].Value.ToString()));
  }
}

Это работает как ожидалось: вы остаетесь с полностью заполненным List<int>.

Вопрос. Как вы могли бы переписать или улучшить этот алгоритм с помощью LINQ для поиска GridView для всех строк, у которых есть их Checkbox selected/checked?

4b9b3361

Ответ 1

Я уверен, что вы не получите никакого улучшения производительности, но это может немного облегчить чтение:

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

Опять же, не уверен, что это имеет значение. Кроме того, почему вы конвертируете в строку, а затем в int? Что-то Convert.ToInt32 не может сделать для вас?

Ответ 2

Я не уверен, что Rows IEnumerable они могут и не быть, но я собираюсь предположить, что они

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

Я только что сделал это в блокноте, там может быть ошибка компиляции. Но так вы можете сделать то же самое с Linq.

Ответ 3

У меня есть нечто подобное, но я использовал его в нескольких местах, поэтому я создал метод расширения.

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

Итак, теперь я могу сделать что-то со всеми проверенными строками. Компилятор довольно хорош в выводе типов, но иногда мне нужно явно объявить checkRows как тип IEnumerable.

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