Click here to Skip to main content
Click here to Skip to main content
Alternative Tip/Trick

Tagged as

Alternating Types in Bound Repeater

, 15 Jul 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
In this alternate version, we take into account the possibility that binding to a list of different types may cause compile errors.

Variation: Alternating Data Types

Suppose I wanted to expand the example further to support binding a list of different types of classes (say, Animal and Human). The binding code would get very complicated, as the bound contents inside of placeholders still get evaluated even when the placeholders are not visible.

To simplify the binding code, you can use a repeater to wrap the objects of different types (pay particular attention to the use of the ListWrap function):

<%@ Page Language="C#" AutoEventWireup="true" %>

<script runat="server">

  // Sample class we can use for binding.
  public class Animal
  {
    public Boolean CanFly { get; set; }
    public String Description { get; set; }
  }

  // Another sample class for binding.
  public class Human
  {
    public String Name { get; set; }
    public String Description { get; set; }
  }

  // Setup binding in page load.
  protected void Page_Load(Object sender, System.EventArgs e)
  {
    rpItems.DataSource = new List<Object> {
      new Animal  {CanFly = false, Description = "Duck"},
      new Animal  {CanFly = true, Description = "Duck"},
      new Animal  {CanFly = false, Description = "Duck"},
      new Animal  {CanFly = true, Description = "Goose!"},
      new Human  {Name = "Elephant Man", Description = "I am not an animal!"}};
    rpItems.DataBind();
  }

  // Helper function to wrap a single item in a list if it is of the specified type.
  protected List<Object> ListWrap<SomeType>(Object item)
  {
    List<Object> returnList = new List<object>();
    if (item is SomeType)
    {
      returnList.Add(item);
    }
    return returnList;
  }

</script>

<html>
<head>
    <title>Markup Conditions Using Bound Code Block</title>
</head>
<body>
    <form id="frmMain" runat="server">

      <!-- This is our main data bound control. -->
      <asp:Repeater runat="server" ID="rpItems">
        <HeaderTemplate>
          <ul>
        </HeaderTemplate>
        <ItemTemplate>
          <li>

            <%-- This repeater is bound to a list with one or zero animals. --%>
            <asp:Repeater runat="server" DataSource="<%# ListWrap<Animal>(Container.DataItem)%>">
              <ItemTemplate>

                <!--  We use placeholder visibility to use different markup depending on the bound value. -->
                <asp:PlaceHolder runat="server" Visible="<%# (Container.DataItem as Animal).CanFly%>">
                  <b>I can fly!</b>
                </asp:PlaceHolder>
                <asp:PlaceHolder runat="server" Visible="<%# !(Container.DataItem as Animal).CanFly %>">
                  I can't fly.
                </asp:PlaceHolder>
                <%# HttpUtility.HtmlEncode(((Animal)Container.DataItem).Description) %>

              </ItemTemplate>
            </asp:Repeater>

            <%-- This repeater is bound to a list with one or zero humans. --%>
            <asp:Repeater runat="server" DataSource="<%# ListWrap<Human>(Container.DataItem)%>">
              <ItemTemplate>
                <%# HttpUtility.HtmlEncode((Container.DataItem as Human).Name)%>:
                "<%# HttpUtility.HtmlEncode((Container.DataItem as Human).Description)%>"
              </ItemTemplate>
            </asp:Repeater>

          </li>
        </ItemTemplate>
        <FooterTemplate>
          </ul>
        </FooterTemplate>
      </asp:Repeater>

    </form>
</body>
</html>
<%@ Page Language="vb" AutoEventWireup="false" %>

<script runat="server">

  ' Sample class we can use for binding.
  Public Class Animal
    Public Property CanFly As Boolean
    Public Property Description As String
  End Class

  ' Another sample class for binding.
  Public Class Human
    Public Property Name As String
    Public Property Description As String
  End Class

  ' Setup binding in page load.
  Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    rpItems.DataSource = New List(Of Object) From {
        New Animal With {.CanFly = False, .Description = "Duck"},
        New Animal With {.CanFly = True, .Description = "Duck"},
        New Animal With {.CanFly = False, .Description = "Duck"},
        New Animal With {.CanFly = True, .Description = "Goose!"},
        New Human With {.Name = "Elephant Man", .Description = "I am not an animal!"}}
    rpItems.DataBind()
  End Sub

  ' Helper function to wrap a single item in a list if it is of the specified type.
  Protected Function ListWrap(Of SomeType)(ByVal item As Object) As List(Of Object)
    Dim returnList As New List(Of Object)()
    If TypeOf item Is SomeType Then
      returnList.Add(item)
    End If
    Return returnList
  End Function

</script>

<html>
<head>
    <title>Markup Conditions Using Bound Code Block</title>
</head>
<body>
    <form id="frmMain" runat="server">

      <!-- This is our main data bound control. -->
      <asp:Repeater runat="server" ID="rpItems">
        <HeaderTemplate>
          <ul>
        </HeaderTemplate>
        <ItemTemplate>
          <li>

            <%-- This repeater is bound to a list with one or zero animals. --%>
            <asp:Repeater runat="server"
              DataSource="<%# ListWrap(Of Animal)(Container.DataItem)%>">
              <ItemTemplate>

                <!--  We use placeholder visibility to use different markup depending on the bound value. -->
                <asp:PlaceHolder runat="server" Visible="<%# DirectCast(Container.DataItem, Animal).CanFly%>">
                  <b>I can fly!</b>
                </asp:PlaceHolder>
                <asp:PlaceHolder runat="server" Visible="<%# Not DirectCast(Container.DataItem, Animal).CanFly %>">
                  I can't fly.
                </asp:PlaceHolder>
                <%# HttpUtility.HtmlEncode(DirectCast(Container.DataItem, Animal).Description) %>

              </ItemTemplate>
            </asp:Repeater>

            <%-- This repeater is bound to a list with one or zero humans. --%>
            <asp:Repeater runat="server"
              DataSource="<%# ListWrap(Of Human)(Container.DataItem)%>">
              <ItemTemplate>
                <%# HttpUtility.HtmlEncode(DirectCast(Container.DataItem, Human).Name)%>:
                "<%# HttpUtility.HtmlEncode(DirectCast(Container.DataItem, Human).Description)%>"
              </ItemTemplate>
            </asp:Repeater>

          </li>
        </ItemTemplate>
        <FooterTemplate>
          </ul>
        </FooterTemplate>
      </asp:Repeater>

    </form>
</body>
</html>

When the item is of the incorrect type, the repeater gets bound to an empty list, and the binding code inside of a repeater bound to an empty collection does not get evaluated. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

AspDotNetDev
Web Developer
United States United States
  • Managing Your JavaScript Library in ASP.NET (if you work with ASP.net and you don't read that, you are dead to me).
  • Graduated summa cum laude with a BS in Computer Science.
  • Wrote some articles and some tips.
  • DDR ("New high score? What does that mean? Did I break it?"), ping pong, and volleyball enthusiast.
  • Software I have donated to (you should too):

Comments and Discussions

 
GeneralMy vote of 4 PinmemberDiego Vargas15-Jul-13 13:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.1411023.1 | Last Updated 15 Jul 2013
Article Copyright 2013 by AspDotNetDev
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid