Question

Consider the current algorithm below that iterates through a GridView's rows to find whether the contained Checkbox is selected/checked.

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

This works as expected: you're left with a fully populated List<int>.

Question: How would you or could you re-write or improve this algorithm using LINQ to search the GridView for all the rows who have their Checkbox selected/checked?

Was it helpful?

Solution

I'm pretty sure you're not going to get any performance improvement from this, but it might make it slightly easier to read:

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

Again, not sure it makes a difference. Also, why are you converting to a string then to an int? Is there something Convert.ToInt32 can't do for you?

OTHER TIPS

I am not sure if Rows is IEnumerable they may not be, but I am going to assume they are

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 just did this in notepad, there might be a compile error in there. But this is how you could do the same thing with Linq.

I have something similar but I was using it in more than one place so I created an extension method.

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

So now I can do something with all the checked rows. The compiler is pretty good at deducing the types but occasionally I need to explicitly declare checkedRows as type IEnumerable.

gvTasksToBill.ActOnCheckedRows("RowLevelCheckBox", checkedRows =>
{
    foreach (int id in checkedRows)
    {
       // do something with id
    }
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top