LINQ and the ASP.NET Repeater control

Posted by: Malcolm Sheridan , on 8/27/2009, in Category ASP.NET
Views: 36920
Abstract: The following article demonstrates how to bind data to an ASP.NET Repeater control and find the selected row using LINQ.
LINQ and the ASP.NET Repeater control
 
I was recently asked a question about the ASP.NET Repeater control and I thought it would make a good article. One of my colleagues had a repeater control, and in each row they had a radio button, along with several columns of data to display to the user. One of the columns of data was a unique identifier that identified which customer the user was browsing. My colleague couldn’t work out how to find the unique identifier for the selected customer. I said use LINQ! To demonstrate this I’m going to create some fake data to show you how to handle this scenario. 
To begin with open Visual Studio 2008 and choose File > New > Web > ASP.NET Web Application. The first thing to do is to create a class that will be the structure of our data. Add a new class to the project and name it People. Add the following code to the People class:
 
C#
 
public class People
{
public int UniqueId { get; set; }
      public string GivenName { get; set; }
      public string Surname { get; set; }
      public int Height { get; set; }
      public int ShoeSize { get; set; }
      public int Age { get; set; }       
}
  
VB.NET
 
Public Class People
Private privateUniqueId As Integer
Public Property UniqueId() As Integer
      Get
            Return privateUniqueId
      End Get
      Set(ByVal value As Integer)
            privateUniqueId = value
      End Set
End Property
       Private privateGivenName As String
       Public Property GivenName() As String
             Get
                   Return privateGivenName
             End Get
             Set(ByVal value As String)
                   privateGivenName = value
             End Set
       End Property
       Private privateSurname As String
       Public Property Surname() As String
             Get
                   Return privateSurname
             End Get
             Set(ByVal value As String)
                   privateSurname = value
             End Set
       End Property
       Private privateHeight As Integer
       Public Property Height() As Integer
             Get
                   Return privateHeight
             End Get
             Set(ByVal value As Integer)
                   privateHeight = value
             End Set
       End Property
       Private privateShoeSize As Integer
       Public Property ShoeSize() As Integer
             Get
                   Return privateShoeSize
             End Get
             Set(ByVal value As Integer)
                   privateShoeSize = value
             End Set
       End Property
       Private privateAge As Integer
       Public Property Age() As Integer
             Get
                   Return privateAge
             End Get
             Set(ByVal value As Integer)
                   privateAge = value
             End Set
       End Property
End Class
 
The UniqueId property will be the unique identifier for the user, so naturally we do not want to show this to the user. The next step is to add a repeater control to the default.aspx page. Add the following code:
 
<asp:Repeater ID="rptPeople" runat="server"
            OnItemDataBound="rptPeople_ItemDataBound">
<HeaderTemplate>
            <table>
</HeaderTemplate>
      <ItemTemplate>
            <tr>
            <td>
                  <asp:RadioButton ID="rdoSelected" GroupName="Person"
                            TextAlign="Right" runat="server"
                            Text='<%# Eval("GivenName") %>' />
                  <asp:HiddenField ID="hdnUniqueId" runat="server"
                            Value='<%# Eval("UniqueId") %>' />
</td>
            <td>
                  <asp:Label ID="Label3" runat="server"
                            Text='<%# Eval("Surname") %>' />
</td>
            <td>
                  <asp:Label ID="lblSurname" runat="server"
                            Text='<%# Eval("Height") %>' />
</td>
            <td>
                  <asp:Label ID="Label1" runat="server"
                            Text='<%# Eval("ShoeSize") %>' />
</td>
            <td>
                  <asp:Label ID="Label2" runat="server"
                            Text='<%# Eval("Age") %>' />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
            </table>
</FooterTemplate>
</asp:Repeater>
<asp:Button ID="btnSubmit" runat="server"
                Text="Submit" OnClick="Button1_Click" />
 
If you ran the code right now, the user would be able to select every radio button, even though I have specified a GroupName. This is because the repeater control mangles the GroupName when it is rendered to the browser. The workaround for this is the following JavaScript I found here:
 
<script language="javascript" type="text/javascript">
        function SetUniqueRadioButton(nameregex, current) {
            re = new RegExp(nameregex);
            for (i = 0; i < document.forms[0].elements.length; i++) {
                elm = document.forms[0].elements[i]
                if (elm.type == 'radio') {
                    if (re.test(elm.name)) {
                        elm.checked = false;
                    }
                }
            }
            current.checked = true;
        }       
</script>
 
This code needs to be set when an item is bound to the repeater. Add the following ItemDataBound code:
 
C#
 
protected void rptPeople_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem)
      {
            return;
}
RadioButton rdo = e.Item.FindControl("rdoSelected") as RadioButton;
      string script = "SetUniqueRadioButton('rptPeople.*Person',this)";
      rdo.Attributes.Add("onclick", script);
}
 
VB.NET
 
Protected Sub rptPeople_ItemDataBound(ByVal sender As Object, ByVal e As RepeaterItemEventArgs)
If e.Item.ItemType <> ListItemType.Item AndAlso e.Item.ItemType <> ListItemType.AlternatingItem Then
             Return
End If
Dim rdo As RadioButton = TryCast(e.Item.FindControl("rdoSelected"), RadioButton)
       Dim script As String = "SetUniqueRadioButton('rptPeople.*Person',this)"
       rdo.Attributes.Add("onclick", script)
End Sub
 
That will ensure the user can only select one radio button at a time, which is normal functionality. To add data to the people class, add the following code to the page load event:
 
C#
 
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
      {
            List<People> people = new List<People>();
            people.Add(new People()
            {
                  GivenName = "Malcolm",
                  Surname = "Sheridan",
                  Age = 32,
                  Height = 185,
                  ShoeSize = 13,
                  UniqueId = 1
});
            people.Add(new People()
            {
                  GivenName = "Suprotim",
                  Surname = "Argawal",
                  Age = 28,
                  Height = 175,
                  ShoeSize = 10,
                  UniqueId = 2
});
           rptPeople.DataSource = people;
            rptPeople.DataBind();
}     
}
 
VB.NET
 
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
If (Not IsPostBack) Then
             Dim people As New List(Of People)()
                  people.Add(New People() With {.GivenName = "Malcolm", .Surname = "Sheridan", .Age = 32, .Height = 185, .ShoeSize = 13, .UniqueId = 1})
                  people.Add(New People() With {.GivenName = "Suprotim", .Surname = "Argawal", .Age = 28, .Height = 175, .ShoeSize = 10, .UniqueId = 2})
                  rptPeople.DataSource = people
                  rptPeople.DataBind()
End If
End Sub
 
The last thing to do is to find out which row the user has selected. For this task I’m going to use LINQ. Add the following code to find the selected user:
 
C#
 
protected void Button1_Click(object sender, EventArgs e)
{
var query = (from p in rptPeople.Items.OfType<RepeaterItem>()
                  let o = p.Controls[1] as RadioButton
                  let hid = p.Controls[3] as HiddenField
                  where o.Checked
                  select new
                  {
                        GivenName = o.Text,
                        UniqueId = hid.Value
}).Single();
Response.Write(query.UniqueId);
}
 
VB.NET
 
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim query = ( _
    From p In rptPeople.Items.OfType(Of RepeaterItem)() _
    Let o = TryCast(p.Controls(1), RadioButton) _
    Let hid = TryCast(p.Controls(3), HiddenField) _
    Where o.Checked _
    Select New With {Key .GivenName = o.Text, Key .UniqueId = hid.Value}).Single()
Response.Write(query.UniqueId)
End Sub
 
To see which radio button is selected, I am using the let keyword. This creates a temporary variable only available to the LINQ query. I also have another local variable that finds the UniqueId, which assigns the value to the hid variable. Finally the Single method is called to return the single record. If you run the project now and select a customer, the UniqueId will be displayed:
 
RadioButton
 
This is another good reason to love LINQ!

The entire source code of this article can be downloaded over here

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Malcolm Sheridan is a Microsoft awarded MVP in ASP.NET, a Telerik Insider and a regular presenter at conferences and user groups throughout Australia and New Zealand. Being an ASP.NET guy, his focus is on web technologies and has been for the past 10 years. He loves working with ASP.NET MVC these days and also loves getting his hands dirty with jQuery and JavaScript. He also writes technical articles on ASP.NET for SitePoint and other various websites. Follow him on twitter @malcolmsheridan


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!

Categories

JOIN OUR COMMUNITY

POPULAR ARTICLES

C# .NET BOOK

C# Book for Building Concepts and Interviews

Tags

JQUERY COOKBOOK

jQuery CookBook