September 6, 2010  
  You are here:  Blog
LINQ to Joe Archive
Module Border Module Border
My Book

C#


VB

Module Border Module Border

Using LINQ to Obtain a Control Reference in an ASP.NET Repeater Item's ControlCollection
 
Location: BlogsLINQ to Joe    
Posted by: Joe Rattz 1/23/2009 2:22:41 PM

I haven't been blogging about LINQ much, but I am making it a new year's resolution to blog more frequently about LINQ.  Now, don't expect daily or even weekly blog posts because I am just not as prolific as some bloggers.  I don't know how some bloggers do it.  But, I do plan on blogging more frequently.

One of my favorite, but under-utilized, ASP.NET controls is the Repeater.  I think it exemplifies what it is that we like so much about the web; that is, the graphic representation of data.  Sure, I use web grids more frequently, but when you have multiple instances of data that just doesn't fit in a single line well, the Repeater is the answer.  Consider listings of homes for sale, or cars.  You typically see an image of the house or car, and several fields of information.  There are usually so many fields, that the data will just not fit in a single line in a grid.  Plus, the image would make the line very tall.  Using a Repeater, each repeating instance of data can have a format and occupy a rectangular screen space that is much taller than a row in a web grid, and you are not locked into an NxN grid.  Here are a couple of examples of repeaters I have used:

NewspaperWithRepeaters.jpg

In the image above, I have a page that is a mock-up of a newspaper, complete with columns.  The idea with this page is here is all the news that is relevant to you, and it includes the user's Orders, Credits, and Invoices.  Each item in one of the columns is a link to the item on another page where they can see all the data associated with that item.  This page is neat because it lets the user see all their items from the week on a single page.  Like a newspaper, you can see the price of the newspaper in the top right corner, and you can see a wink to the MasterCard "priceless" commericals there.  That page has three Repeaters on it; one each for the Orders, Credits, and Invoices.  Notice that each item in the Repeater has a specific format, and that the format for each Repeater (column) is slightly different.  This is the beauty of the Repeater.

In the image below is a Repeater I use that contains a list of stores the user can import into their account.  Again we are looking at repeating items with each item having a format.  Please notice that there is a checkbox in each repeating item.  Also notice that there is a Select All checkbox outside the Repeater.  The purpose of the Select All checkbox is to select the checkbox in each repeating item.

MissingStoresWithRepeater.jpg

On that page, I use a third-party set of web UI controls and during a recent upgrade of that control suite, something broke.  When this happens, I need to create a sample application to demonstrate the problem, and the simpler it is, the better.  As is always the case, my real application is too big, too complex, and dependent on too many environmental conditions to be able to provide the real page.  Below is an image of the sample application I created to reproduce the problem that I could provide to the control's vendor.

RepeaterCheckboxes.jpg

In the image above, you can see a Select All checkbox followed by a list of checkboxes below it.  Those checkboxes are items in a Repeater.  When the user clicks the Select All checkbox, an AJAX postback is made to some code that enumerates through the Repeater's items, finds the checkbox in each item's template (ControlCollection), and checks (or unchecks depending on the state of the Select All checkbox) the Repeater item's checkbox.

Now here's probably the worst part of using a Repeater, dealing with the item's template.  Since the Repeater uses a template, to obtain a reference to any control in the template, you must find the control in the Repeater item's ControlCollection.  Prior to LINQ, that meant enumerating through the item's ControlCollection checking each control to see if it is the one you want.  With LINQ, that is no longer necessary.  Here is my code to obtain a reference to the CheckBox control in each item:


    protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
    {
        foreach (RepeaterItem item in Repeater1.Items)
        {
            CheckBox cb = (CheckBox)item.Controls
                                        .Cast<Control>()
                                        .Where(c => c.ID == "CheckBox2")
                                        .SingleOrDefault();
            if (cb != null)
            {
                cb.Checked = CheckBox1.Checked;
            }
        }
    }

Notice that I enumerate through the Repeater's items.  Next, I call the Cast operator on each item's ControlCollection (named Controls) because ControlCollection is a legacy collection that doesn't implement IEnumerable<T>.  I then call the Where operator on the sequence of Control objects returned by the Cast operator to find just the controls whose ID is equal to the ID I specified for the CheckBox in the template, which is "CheckBox2".  Last, I call the SingleOrDefault operator to get a reference to that single control.  I then check to make sure I got a reference, as opposed to null, and if I did get a reference, I set that control's Checked property equal to the Select All checkbox's Checked property.  Voila, just that easy with a LINQ query, I now have a reference to a control in an ASP.NET Repeater control item's ControlCollection.

This is a fine demonstration of how to use LINQ to query legacy collections that do not implement the IEnumerable<T> interface, as well has how to easily find a control by ID in a ControlCollection.  Who said LINQ isn't fun?


 

Copyright ©2009 Joe Rattz
Permalink |  Trackback

Comments (2)   Add Comment
Re: Using LINQ to Obtain a Control Reference in an ASP.NET Repeater Item's ControlCollection    By Fabrice on 10/21/2009 12:07:58 PM
What's wrong with the standard way of doing it?: item.FindControl("CheckBox2")

Re: Using LINQ to Obtain a Control Reference in an ASP.NET Repeater Item's ControlCollection    By host on 10/21/2009 12:09:54 PM
@Fabrice:

Nothing wrong with that but now we have another way to do it that provides more control and can return more than a single control.


Your name:
Title:
Comment:
Add Comment   Cancel 
 
 
Home|Forums|Blog|LINQ Extras|Contact Me|Book Reviews
  Copyright (c) 2010 LINQDev Terms Of Use Privacy Statement