1. Technology
An introduction to Data-Bound ASP.NET List Controls
First steps in using the Repeater ASP.NET web server control. Learn how to data bind multi-record controls. Understanding the DataBinder class and the DataBinder.Eval method.
 Source Code
• Download Source Code
 Join the Discussion
"Post your views and comments to this chapter of the free Asp.Net Delphi Programming Course"
Discuss!
 Related Resources
• A Beginner's Guide to Asp.Net Programming for Delphi developers.TOC

Welcome to the 21st chapter of the FREE online programming course:
A Beginner's Guide to Asp.Net Programming for Delphi developers.
DataBinder and Multi-Record controls: Repeater

Back in the last two chapters, we've looked at two different approaches to data binding in ASP.NET web applications:

  • The first approach was used to data bound list controls for selecting choices like ListBox, RadioButtonList or DropDownList. We were limited by working with particular properties (DataSource, DataTextField, DataValueField, etc) of those controls.
  • The second approach allowed data binding "plain" HTML and/or binding individual properties of various web server controls by creating custom binding expressions.
By combining those two approaches, in terms of data binding multiple rows of data along with custom binding expressions, we have the power to construct custom "multi-row" HTML layout.

Throughout this chapter, you'll learn about the following:

  • Repeater Web Server control
  • The DataBinder class
  • Using DataBinder.Eval (late binding)
  • Omitting DataBinder.Eval (early binding)
  • Multi-Record Web Server List Controls
    You can use several different Web server controls to display data in list form. Repeater, DataList and DataGrid are data-aware web server control that can be bound to a variety of datasources. While these controls share certain common features, they also differ in terms of the functionality they offer.

    Despite their similarities, each of these Web controls has their individual advantages and disadvantages. In designing data-driven Web applications, ASP.NET developers often find themselves wondering which of these three controls is the "best" one.

    The Repeater Web server control
    The Repetaer is the most lightweight of all list controls as it provides no default rendering of its own. While it provides the most flexibility in the rendered HTML, it is the "worst" one to handle. The output of the Repeater is defined by specifying layout, formatting and styles using templates. The list Repeater will render can be vertical, horizontal, all on one line, or in any format you specify.
    To define how items are displayed by Repeater, at least the ItemTemplate must be provided.

    An example: creating an ordered list output using the Repeater control
    It's a common practice to add ordered items on a web page that look like:

    1. First item
    2. Second item
    3. Third item
    The HTML used to construct this output is:

    <ol>
      <li>First item</li>
      <li>Second item</li>
      <li>Third item</li>
    </ol>
    

    If the items you use in the example output above (simple read only output of HTML) come from some datasource, your best option is to use the Repeater control.

    The ordered list HTML element is "opened" by the "<ol>" - you might think of this as the "header"
    Individual list items are surrounded by the "<li>" and "</li>" tags.
    The list is "closed" with the "</ol>" - think of this as the "footer".

    When such an output is required using the Repeater control, the HeaderTemplate, ItemTemplate and FooterTemplate can be specified.

    Repeater in Delphi ASP.NET applications
    Let's try creating a basic ... bah, why mess with basics, let's start with a "real-world" example:

    Start Delphi, open your ASP.NET test project and add a new web form to it. Name the unit "wfRepeaterExample" (the web page class is "TwfRepeaterExample").
    Switch to design view and drop a Repeater (ID = "Repeater1") on the web form. This is what you should have:

    Repeater at design-time, no templates specified

    The "aspx/html" view is very simple:

    <form runat="server">
      <asp:Repeater
        id="Repeater1"
        runat="server">
      </asp:Repeater>
    </form>
    

    Repeater.DataSource
    As described in the data-binding intro chapter the DataSource property defines the source of data for the control - and is used for populating the list. A standard ArrayList object can be set for the DataSource.

    Let's create a custom class that will be added to the ArrayList used as the Repeater's DataSource.
    Go to the code-behind (".pas" view) and define a custom TColorEntry class:

    type
      TColorEntry = class
      private
        fColorValue: Color;
      public
        property ColorValue : Color read fColorValue;
    
        constructor Create(colorValue : Color);
        function ToHTML : string;
      end;
    ...
    implementation
    ...
    { TColorEntry }
    constructor TColorEntry.Create(colorValue: Color);
    begin
      inherited Create;
    
      self.fColorValue := colorValue;
    end;
    
    function TColorEntry.ToHTML: string;
    begin
      result := ColorTranslator.ToHtml(ColorValue);
    end; 
    

    The TColorEntry class has one property named "ColorValue" and one function named "ToHTML". The constructor of the TColorEntry receives a System.Drawing.Color value.

    An ArrayList of TColorEntry objects will be used as the DataSource property for the Repeater control.

    Define a variable called "ColorList" and a procedure "BuildColorList" in the private section of the TwfBinderSimple interface.

    TwfBinderSimple = class(System.Web.UI.Page)
    ...
    private
      ColorList : ArrayList;
      procedure BuildColorList();
    ...
    implementation
    ...
    procedure TwfRepeaterExample.BuildColorList;
    begin
      ColorList := ArrayList.Create;
    
      ColorList.Add(TColorEntry.Create(Color.Red));
      ColorList.Add(TColorEntry.Create(Color.Green));
      ColorList.Add(TColorEntry.Create(Color.Blue));
    end;
    

    Uh, oh. Now back to web page programming. In the web form's Page_Load handler add the following:

    procedure TwfRepeaterExample.Page_Load(
      sender: System.Object; 
      e: System.EventArgs);
    begin
      if NOT Page.IsPostBack then
      begin
        BuildColorList;
    
        Repeater1.DataSource := ColorList;
        Repeater1.DataBind;
      end;
    end;
    

    By now, you already should be familiar with the code above, if you have followed the chapters of this course. Quick clarification: only on the first visit to the page, the ColorList ArrayList object is filled with TColorEntry instances, assigned as the Repeater1's DataSource.

    Note: if you run the page now, you'll get NO html output - this is because you have not specified at least the ItemTemplate for the Repeater. Let's do that now.

    As the "Repeater" in the design mode suggests, switch to the aspx view, let the Repeater's asp.net markup look like:

    <asp:Repeater id="Repeater1" runat="server">
      <headertemplate>
        <ol>
      </headertemplate>
      <itemtemplate>
        <li></li>
      </itemtemplate>
      <footertemplate>
        </ol>
      </footertemplate>
    </asp:Repeater>
    

    The HTML above defines the HeaderTemplate (opening tag "<ol>"), the ItemTemplate (item: "<li></li>") and the FooterTemplate (closing tag "</ol>").

    If you switch to design view, the design time representation of the Repeater finally has some HTML shape. However, there's still NO mention of our TColorValue objects - this is where we introduce the DataBinder class.

    The DataBinder class
    The ASP.NET supplies a static method, called DataBinder.Eval, that evaluates late-bound data-binding expressions and optionally formats the result as a string.

    Switch again to the "aspx" view and add the following binding expression into the Repeater's ItemTemplate:

    <ItemTemplate>
      <li>
        <%# DataBinder.Eval(Container.DataItem,"ColorValue") %>
      </li>
    </ItemTemplate>
    

    What happens at run time? For each of the items in the assigned DataSource - the ColorList ArrayList, since an item is an object of the TColorEntry type, the DataBinder class with its Eval method gets the value from the TColorEntry's property named "ColorValue".

    This is what you get when you run the page, finally:

    Repeater rendering as ordered list at run time

    Note 1: DataBinder.Eval performs late-bound evaluation, using reflection. First the "Container.DatatItem" is casted to "TColorEntry", then the value for the item's "ColorValue" property is retrieved.
    Note 2: For any of the list Web controls, such as DataList, DataGrid, or Repeater, the container parameter should be Container.DataItem.

    Omitting DataBinder, casting to the correct class
    Using DataBinder and its Eval method is really handy, but it has slow performance due to late bound evaluation.

    A much better approach would be to first cast the "Container.DataItem" to the correct class and then use any of the public properties/functions in the binding expression:

    <ItemTemplate>
      <li 
        style='background-color:
          <%# (Container.DataItem as TColorEntry).ToHTML() %>'>
        <%# DataBinder.Eval(Container.DataItem,"ColorValue") %>
      </li>
    </ItemTemplate>
    

    In the above version of the Repeater's ItemTemplate, each item has been assigned a "style" attribute with a specific CSS "background-color" value. Once the Container.DataItem has been casted to TColorEntry, the ToHTML() function is called.

    The final HTML result (at run time) is:

    Repeater in action

    Ah, I almost forgot ... you might receive the following exception (at run time):
    CS0246: The type or namespace name 'TColorEntry' could not be found (are you missing a using directive or an assembly reference?)

    Now what?! Well, to tell the long story in short, you need to add a special page directive on top of the aspx page:

    <%@ Import namespace="wfRepeaterExample"%>
    

    The "Import namespace" directive, explicitly imports a namespace into a page, making all classes and of the imported namespace available to the page. The namespace where the TColorEntry class is defined is "wfRepeaterExample" - the name of the unit where all the code from this example is defined.

    To the next chapter: A Beginner's Guide to ASP.NET Programming for Delphi developers
    That's it for today. In the next chapter we'll continue exploring the topic of data binding in ASP.NET.

    If you need any kind of help at this point, please post to the Delphi Programming Forum where all the questions are answered and beginners are treated as experts.

    A Beginner's Guide to ASP.NET Programming for Delphi developers: Next Chapter >>
    >> Binding the DataList ASP.NET Control with Dynamic Templates

    ©2014 About.com. All rights reserved.