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?
Ответы
Ответ 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
}
});