10

I'm using an ASP.NET Repeater to display the contents of a <table>. It looks something like this:

<table cellpadding="0" cellspacing="0">
    <asp:Repeater ID="checkboxList" runat="server" OnItemDataBound="OnCheckboxListItemBound">
        <ItemTemplate>
            <tr id="itemRow" runat="server">
                <td>
                    Some data
                </td>
            </tr>
        </ItemTemplate>
    </asp:Repeater>
</table>

It works fine, but i'd like to have an if() statement inside the ItemTemplate so i can conditionally determine if i want to print out a <tr> tag.

So i'd like to have something like this:

<table cellpadding="0" cellspacing="0">
    <asp:Repeater ID="checkboxList" runat="server" OnItemDataBound="OnCheckboxListItemBound">
        <ItemTemplate>

            <% if ( (CurrentItemCount % 2) == 0 ) { %?>
            <tr id="itemRow" runat="server">
            <% } %>
                <td>
                    Some data
                </td>
            <% if ( (CurrentItemCount % 2) == 0 ) { %?>
            </tr>
            <% } %>
        </ItemTemplate>
    </asp:Repeater>
</table>

Is there some way i can achieve this?

PS. The CurrentItemCount is just made up. I also need a way to get the current item count inside that if() statement. But i only seem to be able to get it from <%# Container.ItemIndex; %>, which can't be used with an if() statement?

Vivendi
  • 20,047
  • 25
  • 121
  • 196
  • Is there a reason why you can't use a gridview to display tabular data ? – Laurent S. Jun 18 '13 at 12:31
  • @Bartdude Yes, i'm adjusting existing code and i really don't want to rewrite alot of functionality. So if it's possible somehow with my code then i'd really like to stick to that. – Vivendi Jun 18 '13 at 12:33

5 Answers5

23

Another way of doing this (if performance is not a problem):

<ItemTemplate>
  <!-- "If"  -->
  <asp:PlaceHolder runat="server" Visible="<%# MyCondition %>">
    <tr><td></td></tr>
  </asp:PlaceHolder>  
  <!-- "Else" -->
  <asp:PlaceHolder runat="server" Visible="<%# !MyCondition %>">
    <tr><td></td></tr>
  </asp:PlaceHolder>
</ItemTemplate>
maets
  • 750
  • 6
  • 18
  • Well, very much depending on your scenario of course. My experience is that in a normal use case you will end up performing the same instructions within all placeholders multiple times, one for each condition. The instructions within the hidden placeholder will still be executed, even though no markup gets sent to the client. – maets Sep 04 '15 at 18:43
  • when we set Visible to false the markup will not sent to client. – Abdul Basit Sep 05 '15 at 05:34
  • 2
    Yes, but I think that in cases where the visibility condition is not static (determined upon databinding), all logic defined in both placeholders will be evaluated/executed on the server. Possibly causing a performance drop but not necessarily. – maets Sep 07 '15 at 06:45
  • I used this one with no performance problem. My repeater only gets a 100 to 200 rows. Perfect solution for the conditional content. – Matthew MacFarland Sep 23 '16 at 19:04
17

If you're trying yo make a 2 columns table this could do the trick

<%# Container.ItemIndex % 2 == 0 ? "<tr class='itemRow'>" : "" %>
    <td>
       Some data
    </td>
<%# Container.ItemIndex % 2 != 0 ? "</tr> : "" %>

Changed a couple of things: id="itemRow" for all rows would cause repeated ids what is not allowed.

Removed runat="server" since doesn't make sense on this context.

Claudio Redi
  • 67,454
  • 15
  • 130
  • 155
1

I have 2 examples, for the examples i will bind the repeater to a array of strings (demonstration purposes only)

void BindCheckboxList()
{
 checkboxList.DataSource = new string[] { "RowA", "RowB", "RowC", "RowD", "RowE", "RowF", "RowG" };
 checkboxList.DataBind();
}

Example 1: Create a methode in de codebehind casting the bound elements back en evaluate what ever value you'd like.

Create Methode in CodeBehind (example 1):

protected string StringDataEndsWith(object dataElement, string endsWith, string  returnValue)
{
// for now an object of the type string, can be anything.
string elem = dataElement as string;
    if (elem.EndsWith(endsWith))
    {
     return returnValue; 
    }
     else
    {
     return ""; 
    }
}

In the .aspx file (example 1):

<asp:Repeater ID="checkboxList" runat="server">
<HeaderTemplate> 
    <table style="padding:0px;margin:0px;">
</HeaderTemplate> 
<ItemTemplate>
    <%# StringDataEndsWith(Container.DataItem,"A","<tr id=\"itemRow\" runat=\"server\">")  %>
    <td>
        <%# Container.DataItem  %>
    </td>
    <%# StringDataEndsWith(Container.DataItem,"G","</tr>")  %>
</ItemTemplate>
<FooterTemplate>
    </table>
</FooterTemplate>
</asp:Repeater>

Example 2: You could use a direct cast in the .aspx file

DirectCast example (no code behind):

<asp:Repeater ID="checkboxList" runat="server">
<HeaderTemplate> 
    <table style="padding:0px;margin:0px;">
</HeaderTemplate> 
<ItemTemplate>
    <%# Convert.ToString(Container.DataItem).EndsWith("A") ? "<tr id=\"itemRow\" runat=\"server\">" : ""  %>
    <td>
        <%# Container.DataItem  %>
    </td>
    <%# Convert.ToString(Container.DataItem).EndsWith("G") ? "</tr>" : ""  %>
</ItemTemplate>
<FooterTemplate>
    </table>
</FooterTemplate>
</asp:Repeater>

I hope this is what you're looking for. Regards.

0

If you're wanting to do something on every other item, use the alternating item template. http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater.alternatingitemtemplate.aspx

kduenke
  • 181
  • 4
-1

I would use codebehind:

protected void OnCheckboxListItemBound(Object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
    {
        HtmlTableRow itemRow = (HtmlTableRow) e.Item.FindControl("itemRow");
        itemRow.Visible = e.Item.ItemIndex % 2 == 0;
    }
}
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Since i needed to keep the `ID` attribute of the row, this was the best solution for me. – Vivendi Jun 18 '13 at 12:57
  • 11
    This answer does not show how to use an if statement inside an ItemTemplate. It should really just be a comment. – Edward Olamisan Jun 25 '14 at 16:18
  • @edward: but it shows the best way if you want to use an if statement and you use an item template. Best in terms of fail safety in general and also compile time safety. It is also the more readable and maintainable way. Actually even OP has preferred this. I woulnt use ASP.NET if i still want to code classic ASP or PHP. Apart from that i cannot put this all into a comment. – Tim Schmelter Jun 25 '14 at 16:38
  • 2
    It's arguably less readable and maintainable. The standard approach of ASP.NET is to have UI logic in mark up and business logic in the C# file. Putting UI logic into the C# file is almost as bad as ASP and PHP are putting business logic code into the mark up. Here's one of the examples I've found that actually does that correctly: http://stackoverflow.com/a/264445/556649 – Edward Olamisan Jun 25 '14 at 19:26
  • The aspx is for controls and stylesheets(layout) only. Code or logic belongs to codebehind. Imho inline code is for testing or demonstration purposes only apart from `Eval`/`Bind` or javascript. – Tim Schmelter Jun 25 '14 at 19:46
  • Yes, except UI code or logic does not belong into codebehind. – Edward Olamisan Jun 25 '14 at 19:50
  • UI logic is business logic. _No_ code belongs to the UI. You cannot test,compile,maintain,reuse code which is mixed with UI, no intellisense etc, etc. – Tim Schmelter Jun 25 '14 at 19:54
  • @TimSchmelter UI logic is not business logic. "In computer software, business logic or domain logic is the part of the program that encodes the real-world business rules that determine how data can be created, displayed, stored, and changed. It is contrasted with the remainder of the software which might be concerned with lower-level details of managing a database or displaying the user interface, system infrastructure, or generally connecting various parts of the program." http://en.wikipedia.org/wiki/Business_logic – Edward Olamisan Jun 25 '14 at 19:59