Friday, May 01, 2009

Binding data to a Repeater using Lazy Loading (ASP.NET C#)

Lazy loading is a method of only loading data as and when you need it. Rather than loading it on page load, you can define a property that can then be bound to a WebControl.

For example, in the page is an asp:Repeater:

        <asp:Repeater ID="MyRepeater" DataSource='<%# MyData %>' runat="server">
            <HeaderTemplate><ul></HeaderTemplate>
            <ItemTemplate><li><a href="<%# Eval("Url") %>"><%# Eval("Text") %></a> (Record ID: <%# Eval("RecordID") %>)</li></ItemTemplate>
            <FooterTemplate></ul></FooterTemplate>
        </asp:Repeater>

MyData in the DataSource attribute of asp:Repeater is a property defined in the CodeBehind page:

    private DataTable _MyData;
    public DataTable MyData
    {
        get
        {
            if (_MyData == null)
            {
                _MyData = LoadMyData();
            }
            return _MyData;
        }
    }

LoadMyData gets the data you want to show (normally it would be loaded from a database, rather than rows added in this case)

    private DataTable LoadMyData()
    {
        Trace.Write("LoadMyData");
        DataTable dt = new DataTable();
        dt.Columns.Add(new DataColumn("RecordID", Type.GetType("System.Int32")));
        dt.Columns.Add(new DataColumn("Text", Type.GetType("System.String")));
        dt.Columns.Add(new DataColumn("Url", Type.GetType("System.String")));

        DataRow row;
        int index = 1;

        // new row
        row = dt.NewRow();
        // populate row
        row["RecordID"] = index;
        row["Text"] = "Google";
        row["Url"] = "http://www.google.co.uk";
        // add row to table
        dt.Rows.Add(row);

        // increment index
        index++;

        // new row
        row = dt.NewRow();
        // populate row
        row["RecordID"] = index;
        row["Text"] = "Yahoo";
        row["Url"] = "http://www.yahoo.co.uk";
        // add row to table
        dt.Rows.Add(row);

        return dt;
    }

The Trace.Write is there to show that the data isn't loaded if it is not bound to a WebControl in the page. This can be tested by turning on tracing (adding Trace="True" to <%@ Page) and removing DataSource='<%# MyData %>' from the Repeater.

You would then bind the page on load:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            DataBind();
        }
    }

LazyLoadRepeater.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="LazyLoadRepeater.aspx.cs" Inherits="LazyLoadRepeater" Trace="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Lazy Loading</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>Search Engines</h1>
        <asp:Repeater ID="MyRepeater" DataSource='<%# MyData %>' runat="server">
            <HeaderTemplate><ul></HeaderTemplate>
            <ItemTemplate><li><a href="<%# Eval("Url") %>"><%# Eval("Text") %></a> (Record ID: <%# Eval("RecordID") %>)</li></ItemTemplate>
            <FooterTemplate></ul></FooterTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>

LazyLoadRepeater.aspx.cs:

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

public partial class LazyLoadRepeater : System.Web.UI.Page
{
    private DataTable _MyData;
    public DataTable MyData
    {
        get
        {
            if (_MyData == null)
            {
                _MyData = LoadMyData();
            }
            return _MyData;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            DataBind();
        }
    }

    private DataTable LoadMyData()
    {
        Trace.Write("LoadMyData");
        DataTable dt = new DataTable();
        dt.Columns.Add(new DataColumn("RecordID", Type.GetType("System.Int32")));
        dt.Columns.Add(new DataColumn("Text", Type.GetType("System.String")));
        dt.Columns.Add(new DataColumn("Url", Type.GetType("System.String")));

        DataRow row;
        int index = 1;

        // new row
        row = dt.NewRow();
        // populate row
        row["RecordID"] = index;
        row["Text"] = "Google";
        row["Url"] = "http://www.google.co.uk";
        // add row to table
        dt.Rows.Add(row);

        // increment index
        index++;

        // new row
        row = dt.NewRow();
        // populate row
        row["RecordID"] = index;
        row["Text"] = "Yahoo";
        row["Url"] = "http://www.yahoo.co.uk";
        // add row to table
        dt.Rows.Add(row);

        return dt;
    }
}

No comments: