在重复器的ItemTemplate中的If语句

10

我正在使用ASP.NET的Repeater来显示一个<table>的内容。它看起来像这样:

<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>

它能正常工作,但我想在ItemTemplate中加入一个if()语句,以便可以有条件地确定是否要打印出<tr>标记。

所以我想要像这样的内容:

<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>

有没有办法可以实现这个?

附注:CurrentItemCount只是虚构的。我还需要一种方法来在if()语句中获取当前项目计数。但是我似乎只能从<%# Container.ItemIndex; %>获取它,而这不能与if()语句一起使用?


你不能使用GridView来显示表格数据吗?有什么原因吗? - Laurent S.
@Bartdude 是的,我正在调整现有的代码,我真的不想重写很多功能。所以如果我的代码可以在某种程度上实现,那么我真的想坚持使用它。 - Vivendi
5个回答

23

如果性能不是问题,另一种方法是:

<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
当我们将Visible设置为false时,标记不会发送到客户端。 - Abdul Basit
2
是的,但我认为在能见度条件不是静态的情况下(在数据绑定时确定),两个占位符中定义的所有逻辑都将在服务器上进行评估/执行。可能会导致性能下降,但不一定。 - maets
我使用这个没有性能问题。我的重复器只获取100到200行。对于条件内容来说是完美的解决方案。 - Matthew MacFarland

17

如果你想制作一个双栏表格,这个方法可能有用

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

对一些事情进行了更改:id="itemRow" 会导致重复的id,这是不允许的。

由于在此上下文中没有意义,因此已删除runat="server"


1

我有两个例子,这些例子中我将把重复器绑定到一个字符串数组(仅用于演示目的)。

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

示例1:在代码后端创建一个方法,将绑定的元素强制转换回来并评估任何您想要的值。

在代码后端创建方法(示例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 ""; 
    }
}

在 .aspx 文件中(示例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>

示例2:您可以在.aspx文件中使用直接转换

DirectCast示例(无代码后台):

<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>

我希望这就是你要找的。问候。

0

-1

我会使用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;
    }
}

由于我需要保留行的 ID 属性,这对我来说是最好的解决方案。 - Vivendi
11
这个答案没有展示如何在ItemTemplate内使用if语句。实际上,它应该只是一个评论。 - Edward Olamisan
@edward:但是如果您想使用if语句并且使用项目模板,它会显示最佳方法。从一般的故障安全性和编译时安全性来看,这是最好的方式。它也是更可读和可维护的方式。实际上,即使OP也更喜欢这种方式。如果我仍然想编写经典ASP或PHP代码,我不会使用ASP.NET。除此之外,我无法将所有内容都放入评论中。 - Tim Schmelter
2
这种方式可能会降低代码的可读性和可维护性。ASP.NET 的标准方法是将 UI 逻辑放在标记中,将业务逻辑放在 C# 文件中。将 UI 逻辑放入 C# 文件中几乎与 ASP 和 PHP 将业务逻辑代码放入标记中一样糟糕。以下是我发现的一个实际上正确执行此操作的示例:https://dev59.com/nUXRa4cB1Zd3GeqPt7Eb#264445 - Edward Olamisan
UI逻辑就是业务逻辑。没有任何代码属于UI。你不能测试、编译、维护、重用与UI混合的代码,也没有智能感知等等。 - Tim Schmelter
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接