Saturday, May 04, 2013

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.

1 comment:

Anonymous said...

Thanks -- this helped me out! Wish I wasn't doing Web Forms in 2015, but hey -- never know what you're going to land into haha.