ASP.NET:如何更改<asp:repeater>中每行使用的itemTemplate?</asp:repeater>

时间:2008-12-04 22:29:49

标签: asp.net

现有的代码使用asp:repeater来构建HTML表。 (强调现有设计)。这是生成表的一些部分伪代码:

<asp:repeater OnItemDataBound="ItemDataBound" ... >

   <headertemplate>
      <table>
         <thead>
            <tr>
               <td>Date</td>
               <td>Type</td>
               <td>Action</td>
            </tr>
         </thread>
   </headertemplate>

   <itemtemplate>
      <tr>
         <td><%# GetTextForThis((MyItem)Container.DataItem) %></td>
         <td><%# GetTextForThat((MyItem)Container.DataItem) %></td>
         <td><%# GetTextForTheOther((MyItem)Container.DataItem) %></td>
      </tr>
   </itemtemplate>

   <footertemplate>
         </tbody>
      </table>
   </footertemplate>

</asp:repeater>

但是现在需要(某些)项目以不同方式显示,并且需要使用COLSPAN=3完成,并且整个项目将是一个单元格:

   <itemtemplate>
      <tr>
         <td colspan="3">
            <img src="<%# GetImageSrcForFoo((MyItem)Container.DataItem) %>
            <a href="<%# GetHrefForFoo((MyItem)Container.DataItem) %>
         </td>
      </tr>
   </itemtemplate>

假设:

  • 该页面使用转发器构建HTML表格
  • 设计需要一些表格行来跨列

我该怎么做?

希望类似:

   <itemtemplate id="thisThatTheOtherItemTemplate">
      <tr>
         <td><%# GetTextForThis((MyItem)Container.DataItem) %></td>
         <td><%# GetTextForThat((MyItem)Container.DataItem) %></td>
         <td><%# GetTextForTheOther((MyItem)Container.DataItem) %></td>
      </tr>
   </itemtemplate>


   <itemtemplate id="fooItemTemplate">
      <tr>
         <td colspan="3">
            <img src="<%# GetImageSrcForFoo((MyItem)Container.DataItem) %>
            <a href="<%# GetHrefForFoo((MyItem)Container.DataItem) %>
         </td>
      </tr>
   </itemtemplate>

并以某种方式神奇地能够让OnDataBind事件告诉转发器使用哪个模板。这可能吗?

答案

虽然两个答案都是正确和好的,但我宁愿使用第一个建议;这涉及在aspx文件中显示代码,而不是在代码隐藏中手动构建HTML。 (我不想再次在代码中构建HTML)

   <itemtemplate>
      <asp:PlaceHolder ID="thing1" runat="server">
         <tr>
            <td><%# GetTextForThis((MyItem)Container.DataItem) %></td>
            <td><%# GetTextForThat((MyItem)Container.DataItem) %></td>
            <td><%# GetTextForTheOther((MyItem)Container.DataItem) %></td>
         </tr>
      </asp:PlaceHolder>

      <asp:PlaceHolder ID="thing2" visible="false" runat="server">
         <tr>
            <td colspan="3">
               <img src="<%# GetImageSrcForFoo((MyItem)Container.DataItem) %>
               <a href="<%# GetHrefForFoo((MyItem)Container.DataItem) %>
            </td>
         </tr>
   </itemtemplate>

并在代码隐藏中:

protected void myRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
   // if the data bound item is an item or alternating item (not the header etc)
   if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
   {
      // get the associated object
      Object item = .Item.DataItem;
      if (item == null)
         return;

      Control thing1 = e.Item.FindControl("thing1");
      Control thing2 = e.Item.FindControl("thing2");

      if (item is MyClassThatICreated)
      {
         thing1.Visible = false;
         thing2.Visible = true;
      }
      else
      {
         thing1.Visible = true;
         thing2.Visible = false;
      }
      ...
}

2 个答案:

答案 0 :(得分:6)

在项目模板中放置两个ASP:占位符控件。在代码隐藏中,在ItemDataBound事件上,确定要显示的样式,并隐藏一个占位符。

答案 1 :(得分:3)

Jonathan建议的替代方法是在ItemDataBound事件中动态构建后端项目,有些人发现更容易使用,而不是切换可见性。

我个人在这种情况下只会输入一个文字,模式=“Passthrough”并将在后端构建它。