SingingEels : Development Community & Resource

Login

Articles

  • ADO.NET (2)
  • ASP.NET (36)
  • LINQ (5)
  • Security (2)
  • Silverlight (3)
  • SQL (7)
  • Standards (5)
  • WCF (2)

Syndication

  • Articles RSS
  • Blogs RSS

Contribute

  • Our Authors List
  • Member Sign-Up
  • Suggestions Box

The ListView Dominates The Repeater

(Aug 07 2007 - 07:43:15 AM by Timothy Khouri) - [print article]

The Repeater control that was introduced with the dawn of ASP.NET encapsulated much needed functionality and has given web developers a customizable, object oriented way of repeating any kind of data (that doesn't belong in a table which is handled by the GridView control). But the new ListView control in ASP.NET 3.5 blows the Repeater control out of the water. This article will discuss the differences between the two controls showing all the powerful features of the ListView control.

The need to "repeat" some HTML data is in almost every dynamic website out there. Every blog (whether written in .NET, PHP, ColdFusion or whatever), every RSS feed and every forum is an example of the need to 'spit out' the same HTML template over and over again, just changing some of the details inside. In my PHP days, I would have to write a 'for loop' and bounce between 'echoing' HTML strings and PHP variables. This is the farthest thing from clean code, object oriented programming or anything that I ever want to do again (and if you don't know what I'm talking about, then be happy... that's like not being able to relate to grandpa's war stories).

The Repeater control allowed you to describe a header and footer template (to specify what HTML should come above and below the list of 'items' that are going to be repeated) and an "item" template (to specify the HTML and server controls that will be used for every item in the enumerable data items that you are bound to). It also has support for an "empty item template" so that you can render some default HTML to the client if the data source that your repeater is bound to happens to be empty. That gives you enough functionality to get the job done, but it still falls down in a few key areas.

Problems with the Repeater

First of all, the notion of a 'header' and 'footer' template is no better than the old PHP (or "classic" ASP) way of doing things. It's not really object oriented, but rather it bares the ignorance of "well, I'm just sending HTML to a web browser", instead of the concept of building objects (that happen to render HTML to a web browser in most cases). The new ListView control steps up to the plate by removing the header/footer templates and instead you use a single LayoutTemplate.

You might be wondering "How does a single template give you the ability to achieve both a header and a footer?" Well, in the LayoutTemplate you can specify a server control (yes, an object!) that will be used as a parent control for each item in the ItemTemplate control from there on. This will make a lot more sense if you look at some code, so let's look at an example of a Repeater control and a ListView control. For now, we'll show the how to achieve the same functionality between the two. Here's the code:

<!--
   DISCLAIMER: I do not recommend using inline eval statements.
   I am only using them for demonstration purposes.
-->


<!-- Using a Repeater -->
<asp:Repeater ID="MyRepeater" runat="server">
   <HeaderTemplate>
       <ul>
   </HeaderTemplate>
   <ItemTemplate>
       <li>
           <%#Eval("SiteAddress") %></li>
   </ItemTemplate>
   <FooterTemplate>
       </ul>
   </FooterTemplate>
</asp:Repeater>

<!-- Using a ListView -->
<asp:ListView ID="MyListView" runat="server">
   <LayoutTemplate>
       <ul>
           <asp:PlaceHolder ID="itemContainer" runat="server" />
       </ul>
   </LayoutTemplate>
   <ItemTemplate>
       <li>
           <%#Eval("SiteAddress") %></li>
   </ItemTemplate>
</asp:ListView>

You should right away see the difference between the two. The fact that you have to break up the "ul" tag in the Repeater is nasty. In fact, it's not even valid HTML. Whereas if you look at the clean, object oriented way of achieving the same thing with the ListView, the code seems a lot nicer. You might be wondering how the ListView knows to look for a control with the ID of "itemContainer". This is nothing magical, but rather it's the default server control ID it will look for (so you can change it to look for something else by changing the ItemContainerID property).

Just to put your mind at ease, both of these above controls will render almost the exact same HTML. Here is what they both look like (which you can see for yourself in the attached source files at the end of the article):

An ASP.NET Repeater control and a ASP.NET 3.5 ListView control displaying the same thing

The Forgetful Repeater

Another major failing of the Repeater control (and this is probably the biggest one) is that you couldn't save/tap into the data you have bound later (whether in an ItemCreated event, or after a post-back etc). This means that if you wanted to use some values that were in the data source that your repeater was bound to, you would have to store it in memory, store and retrieve the values in the ViewState yourself or re-hit your data source every time you wanted to get these values.

The ListView control once again comes to the rescue with the added "DataKeyNames" property (just like the GridView control has in ASP.NET 2.0). This example will show how you can store some values in the DataKeys section of the ListView and retrieve them back later. We'll make another list of websites, but this time they are going to be LinkButtons that, when clicked on, will display the website's "description" on the page. Here's the code:

<!-- Here is the ASP.NET code. Notice the DataKeyNames property -->
<asp:ListView ID="MyListView" runat="server" DataKeyNames="WebSiteName,Description">
   <LayoutTemplate>
       <ul>
           <asp:PlaceHolder ID="itemContainer" runat="server" />
       </ul>
   </LayoutTemplate>
   <ItemTemplate>
       <li>
           <asp:LinkButton ID="SiteLink" runat="server" /></li>
   </ItemTemplate>
</asp:ListView>
<p id="SelectedSiteDescription" runat="server" />
// Here is the C# code. Notice I can use those named DataKeyNames.
private void MyListView_ItemCreated(object sender, ListViewItemEventArgs e)
{
   if (e.Item.ItemType == ListViewItemType.DataItem)
   {
       ListViewDataItem currentItem = (ListViewDataItem)e.Item;

       DataKey currentDataKey = this.MyListView.DataKeys[currentItem.DataItemIndex];

       LinkButton SiteLink = (LinkButton)currentItem.FindControl("SiteLink");

       // I can use this value because I set it in the "DataKeyNames" property

       // of the ListView.

       SiteLink.Text = (string)currentDataKey["WebSiteName"];

       SiteLink.Click += delegate
       {
           // I can also use the Description value because it too is in the

           // ListView's DataKeyNames property.

           this.SelectedSiteDescription.InnerText = (string)currentDataKey["Description"];
       };
   }
}

That's a Wrap

From what we've seen alone, the ListView is the right choice for anything the old Repeater control could do. On top of that, the added functionality of the DataKeyNames and the object-oriented style of the LayoutTemplate make it all that much more appealing. However, there is another piece of functionality that is brought to you by the ListView that has been a long time coming in the ASP.NET world, and will be very well received - pagination.

Yes, the ASP.NET 2.0 GridView control has pagination, but that's only for tabular data (things that look like an Excel file). But the new DataPager control allows you to extend the ListView's functionality to utilize pagination as well. That functionality will be discussed in future articles.

The source code I used in the article was written in Visual Studio 2008 Beta 2. You can download it here: SingingEels_ListView_VS_Repeater.zip

  • Aug 13 2007 - 12:19:24 PM atomiton

    Great Post Tim! I just found your blog from Scott Gu's. You go more technical and offer a different perspective. Nice Job! Gives me something to chew on.

  • Aug 30 2007 - 09:38:34 AM dpirs

    Hi, nice Article!

    Can you just suggest what do you suggest to use instead of inline eval statements?

    Thanks

  • Aug 30 2007 - 08:15:15 PM Timothy Khouri

    Instead of eval statements, I would use the ItemCreated event and assign any values that I need to in code behind. This keeps it more "object orientie" (not a real word).

  • Aug 31 2007 - 03:22:59 AM jimibt

    Tim,

    Being a man that loves a challenge, how about 'attempting' an article that combines the functionality of the new listview in 3.5 with the creation of custom controls that is useable in vs2005. i.e. a custom listview control for vs2005. I realise that it'd require tapping into quite a few 'deep' programming subclassing areas, but would be a great 'advanced' article to learn from.

    just an idle thought - and thanks for the content so far...

    jimi

  • Aug 31 2007 - 05:21:20 AM Timothy Khouri

    That's an interesting idea... almost a sort of "how to build your own ListView control in .NET 2.0". I'll see if I can find the time. Although, I will have to admit that I would mostly 'cheat' by decompiling the 3.5 ListView :P

  • Aug 31 2007 - 05:36:20 AM jimibt

    Tim,

    cheat away!! - i won't tell :)

    thanks for 'thinking' about the notion and if you do manage to do it, i think there would be many grateful peeps out there who'd love to implement it in supported 2.0 solutions i'm sure.

You must be logged in to add comments. If you have not already done so, you can create an account here. If you already are a member, you first need to login before you can comment.

Developer / Architect / Author

People to Follow

Experts in the categories related to this article.

  • Jonathan Carter

Related Blogs

These are the most recent blog posts related to this article.

  • Follow up to Self Sorting GridView
  • A Change to the MVC "ActionSelectionAttribute"?
  • How to Handle "Side Content" in ASP.NET MVC
  • LINQ to SQL - Am I Hitting The Database?
  • ASP.NET MVC - Issue with CSS Class Name on ActionLinks

Related Ads

SingingEels.com as of Mar 20 2010 - 11:50:47 AM - (0.265642)