Two Approaches to Avoiding Repeating an Item Template
-
An ex-cow-orker needed to create two sections on an ASP.NET webpage with repeated items. Imagine something that gets rendered to HTML like this:
<h2>First Header</h2>
<div>Item 1</div>
<div>Item 2</div>
<h2>Second Header</h2>
<div>Item 3</div>
<div>Item 4</div>
<div>Item 5</div>To avoid creating two repeaters, they created a single repeater, and then used the pre-render events to add headers to each section. Here's a short version of it (much simplified):
<script runat="server">
Private Sub myRepeater_PreRender(sender As Object, e As System.EventArgs) Handles myRepeater.PreRender
For Each item In myRepeater.Items
If SomeCondition1() Then
Dim headerContainer As PlaceHolder = item.FindControl("myHeader")
AddHeader(headerContainer, "First Header")
End If
If SomeCondition2() Then
Dim headerContainer As PlaceHolder = item.FindControl("myHeader")
AddHeader(headerContainer, "Second Header")
End If
Next
End Sub
</script><asp:Repeater runat="server" ID="myRepeater">
<ItemTemplate>
<asp:PlaceHolder ID="myHeader" runat="server" />
<%-- ...Rest of item template... -->
</ItemTemplate>
</asp:Repeater>Not a bad approach, I think, though I'd probably have just created a nested repeater:
<asp:Repeater runat="server" ID="outerRepeater">
<ItemTemplate>
<h2><%# HttpUtility.HtmlEncode(DirectCast(Container.DataItem, ItemCollection).HeaderText) %></h2>
<asp:Repeater runat="server" DataSource="<%# DirectCast(Container.DataItem, ItemCollection).Items %>">
<ItemTemplate>
<%-- ...Rest of item template... -->
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>Of course, I'd have to split out the collection being bound to into two collections and create some wrapper classes and such, but nothing too difficult. I like this approach more, because you can avoid doing unnecessary processing during the render/binding stages (which just seems like a hack to me). Another reason I prefer my approach is because you could then sort each collection differently. Wh