Oct 02 2006

ASP.NET repeater control - databind with style

Posted by admin under Controls

If I had to name *one* single control as my favorite ASP.NET server control, it would
most probably be the asp:repeater.

When I started ASP.NET programming the datagrid was my best friend - or I wanted it to be - I tried in every way to use it whereever possible. I even used the inline editing features, which I at the time thought was the coolest way possible to write ASP.NET code ( I managed to write code to hide all other rows and only show the current one - the row being edited). With a nicelooking EditTemplate it looked indeed very slick but it really turned into giant and hard to manage code behind files.

Nowadays I always do inserts/editing in its own aspx page.  Listing objects in listfoos.aspx and editing/adding in editfoo.aspx.

So what about the repeater. Well, supporting templates for databound item (my number one feature in a control) - it lets you create your own type of datastructure (with header, footer and rows) but it's up to you how you decide to render it. If you want to render it as a table, fine. Put <table> in header, </table> in footer and <tr><td>item data in here</td></tr> in the template. However if you want a <ul><li></li></ul> structure instead, fine - put <ul> in header, </ul> in footer and the actual li items in the ItemTemplate.

Cause the "problem" with the more complicated ASP.NET databound controls such as the grid is just that they are typically tied to render certain html tags.

So, lets create a little demo - let's databind some repeaters to the MSSQL sample database northwind, the table categories:



    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            rptTable.DataSource = GetTable();
            rptTable.DataBind();

...
...
..

And - first lets use a simple table approach:



    <asp:Repeater ID="rptTable" runat="server">
    <HeaderTemplate>
        <table>
    </HeaderTemplate>
    <ItemTemplate>
        <tr><td>
        <asp:HyperLink id="hlEdit" runat="server" NavigateUrl="#" Text='<%# DataBinder.Eval(Container.DataItem, "CategoryName") %>'>
        </asp:HyperLink>
        </td></tr>
    </ItemTemplate>
    <FooterTemplate>
        </table>
    </FooterTemplate>
    </asp:Repeater>


Not very beautyful, but you get the point:

But now comes the point. Lets change the repeater template like this:



    <HeaderTemplate>
        <ul>
    </HeaderTemplate>
    <ItemTemplate>
        <li>
        <asp:HyperLink id="hlEdit" runat="server" NavigateUrl="#" Text='<%# DataBinder.Eval(Container.DataItem, "CategoryName") %>'>
        </asp:HyperLink>
        </li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
    </FooterTemplate>


and we get a list instead:

And lists are indeed very good for displaying structured data. The cool thing about it is that you can change the looks completely just by using stylesheet:



	<style type="text/css">
ul#navlist
{
margin-left: 0;
padding-left: 0;
white-space: nowrap;
}

#navlist li
{
display: inline;
list-style-type: none;
}

#navlist a { padding: 3px 10px; }

#navlist a:link, #navlist a:visited
{
color: #fff;
background-color: #036;
text-decoration: none;
}

#navlist a:hover
{
color: #fff;
background-color: #369;
text-decoration: none;
}
	
	</style>
...
...
    <asp:Repeater ID="rptStyle2" runat="server">
    <HeaderTemplate>
        <div id="navcontainer">
        <ul id="navlist">
    </HeaderTemplate>
    <ItemTemplate>
        <li>
        <asp:HyperLink id="hlEdit" runat="server" NavigateUrl="#" Text='<%# DataBinder.Eval(Container.DataItem, "CategoryName") %>'>
        </asp:HyperLink>
        </li>
    </ItemTemplate>
    <FooterTemplate>
        </ul>
        </div>
    </FooterTemplate>
    </asp:Repeater>

Now we have a horizontal style list.

My point is - use repeaters instead of the datagrid/gridview. The built in editing features in those controls are simply not worth it, IMHO.  Take control of your rendering - you will have so much more freedom to accomplish what you want.

Note: the CSS style was taken from MaxDesign Listamatic which shows you lots of different CSS styles to apply to lists. But using lists instead of table is not the point in this article - the point is simply : use repeaters instead of grid controls.