Grids, Selection, Checkboxes and Linq

Before I even get started, a quick side note.  I initially assumed I should write LINQ [all caps] since it is an acronym (from what I recall), but I decided to go with the .NET Framework namespace capitalization instead.  I should have learned my lesson with AJAX or Ajax, or however you want to write it. ;)

Ok, back to the point.  I've seen a couple of posts in the Infragistics forums lately asking about checkbox columns.  You see, even though we put some snazzy selection feature into our grids, many end users have had the checkbox selection paradigm pounded into their heads for years.  They're used to it, they like it, and they demand it from you the developer.  The question becomes - is there an easy way to associate checkbox state with row selection?

Rather than have the checkbox toggle the grid's built-in selection mechanism, I think it makes more sense to treat the checked rows as you would have treated selected rows.  The only complexity is getting a collection of checked rows.  Now I use the term complexity loosely here, because getting the checked rows is really just a single for loop away.  But something just feels clumsy about using a for loop to search through all the rows.  What seems like a natural fit for me is Linq. You can use a Linq query to get a collection of rows from the grid based on their checked state.  Here's an example of a method which does just that.

protected RowsCollection GetSelectedRows(UltraWebGrid grid)
{
    var rows =
        from UltraGridRow row in grid.Rows
        where row.Cells.FromKey("check").Value!=null && ((bool)row.Cells.FromKey("check").Value)==true
        select row;
    return rows;
}

 

On the outside this is a simple method that returns a RowsCollection.  However, notice that on the inside there are some different ingredients.  First of all, there's no semi-colons!  Linq expressions can be broken up in to multiple lines, and do not require semi-colons.  Aside from the return parameter (var rows) the expression has 3 parts just like a SQL query.  In the first piece, we're defining the IEnumerable that we'll be iterating over, and assigning 'row' as the loop variable.  Then we set up the 'where', which will act to filter out our results (just like in a SQL query), and we finally define the select statement which will decide what gets returned.  In the example above we're simply returning the rows collection that is being created.  But we could just as easily return a collection of objects, or even us anonymous types here to construct an object with specific properties we want.  As an example:

    var rows =
        from UltraGridRow row in grid.Rows
        where row.Cells.FromKey("check").Value!=null && ((bool)row.Cells.FromKey("check").Value)==true
        select new {ID=(int)row.Cell[0].Value, Value=row.Cell[1].Text};
    return rows;

In the above example, rather than returning a rows collection, we're returning a collection of objects, where the object has 2 properties - ID and Value.  Pretty powerful, and the syntax is short and sweet.

 

I used the checkbox selection problem as an example of where you can use Linq, but that certainly isn't the only place.  I encourage you to try it out yourself.  There are some great resources out there, including blog posts from Scott Gu, and plenty of documentation on MSDN.  If you haven't been introduced to Linq yet, it's time you take the plunge.  You'll be pleasantly surprised. 

2 Comments

  • Hi, I has a problem with a ultrawebgrid. We have a table with 4 columns(name,birthday ,middle name,id), I need to select one row and get the id value that is the first cell, I tried to do, but only see errors, yo can help me!!.

  • @Gustavo - probably best to post this in the infragistics forums (forums.infragistics.com) or to submit a formal incident (www.infragistics.com/gethelp). It sounds like you're probably trying to pull the row out of the grid before databinding is complete - which would give you a null reference exception (since the row doesn't exist).

Comments have been disabled for this content.