WebForms: handling an empty data source in a Repeater control
I have a Repeater generating an unordered list:
<ul> <li>item 1</li> <li>item 2</li> ... </ul>
The problem occurs when the data source has no items. Most of the articles I found add a Label control to the Repeater's FooterTemplate, but I can't do that here (I need a li tag). Here are two methods I have confirmed to be working:
Method 1: using the OnItemDataBound event
Use the following HTML:
<asp:Repeater runat="server" ID="Repeater1" OnItemDataBound="Repeater1_ItemDataBound">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<asp:Label runat="server">
<%# DataBinder.Eval(Container.DataItem, "Name") %>
</asp:Label>
</li>
</ItemTemplate>
<FooterTemplate>
<li runat="server" id="noData" Visible="False">[None found.]</li>
</ul>
</FooterTemplate>
</asp:Repeater>
The OnItemDataBound handler looks like this:
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
var repeater = e.Item.Parent as Repeater;
if (repeater.Items.Count > 0)
return;
var noData = e.Item.FindControl("noData");
if (noData != null)
noData.Visible = true;
}
Since the noData control only appears in the footer I didn't need to check the Item.ItemType property.
Method 2: evaluate the Visible property at run-time
Replace the HTML with:
<asp:Repeater runat="server" ID="Repeater1">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<asp:Label runat="server">
<%# DataBinder.Eval(Container.DataItem, "Name") %>
</asp:Label>
</li>
</ItemTemplate>
<FooterTemplate>
<li runat="server" Visible='<%# DataBinder.Eval(Container.Parent, "Items.Count").ToString() == "0" %>'>
[None found.]
</li>
</ul>
</FooterTemplate>
</asp:Repeater>
The ToString() call is needed because the Eval method returns an object and I had to convert it to something else. I could have converted it to an int, but that would have required a ToString() call anyway.
So, here you have it: two methods of simulating an EmptyTemplate construct in a Repeater control.
Comments