2011-03-15 73 views
0

我正在使用中继器来构建自定义表。但是,如果下一行的巡视路线与之前的行不匹配,我无法弄清楚如何使表格显示小计。嵌套中继器显示匹配父中继器的数据

类似的东西。

row1 tour1 
row2 tour 1 
tour1 subtotal 
row3 tour2 
row4 tour2 
subtotal 
total 

<asp:Repeater ID="ParentRepeater" runat="server" DataSourceID="SqlDataSource1"> 
    <HeaderTemplate> 
     <table border="1"> 
      <tr> 
       <th>TOUR</th> 
       <th>THEME</th> 
       <th>ROUTE</th> 
       <th>DEPT</th> 
      </tr> 
    </HeaderTemplate> 
    <ItemTemplate> 
     <tr> 
      <td><%#Container.DataItem("tour")%></td> 
      <td align="center"><%#Container.DataItem("theme")%></td> 
      <td align="right"><%#Container.DataItem("route")%></td> 
      <td align="right"><%#Container.DataItem("dep7")%></td> 
      <asp:Repeater ID="ChildRepeater" runat="server" 
       DataSourceID="SqlDataSource2"> 
       <HeaderTemplate> 
        <table border="1"> 
         <tr> 
          <th>BOOKNO</th> 
          <th>PARTY</th> 
          <th>TOUR</th> 
          <th>THEME</th> 
          <th>ROUTE</th> 
          <th>DEPT</th> 
          <th>HOME</th> 
          <th>USERID</th> 
         </tr> 
       </HeaderTemplate> 
       <ItemTemplate> 
        <tr> 
         <td align="center"><%#Container.DataItem("bookno") %></td> 
         <td><%#Container.DataItem("party")%></td> 
         <td><%#Container.DataItem("tour")%></td> 
         <td align="center"><%#Container.DataItem("theme")%></td> 
         <td align="right"><%#Container.DataItem("route")%></td> 
         <td align="right"><%#Container.DataItem("dep7")%></td> 
         <td align="right"><%#Container.DataItem("home")%></td> 
         <td align="right"><%#Container.DataItem("userid")%></td> 
        </tr> 
       </ItemTemplate> 
       <FooterTemplate> 
        </table> 
       </FooterTemplate> 
      </asp:Repeater> 
     </tr> 
    </ItemTemplate> 
    <FooterTemplate> 
     </table> 
    </FooterTemplate> 
</asp:Repeater> 

代码背后

Protected Sub ItemBound(ByVal sender As Object, ByVal args As RepeaterItemEventArgs) 
     If args.Item.ItemType = ListItemType.Item Then 
      Dim childRepeater As Repeater = DirectCast(args.Item.FindControl("ChildRepeater"), Repeater) 
      childRepeater.DataSource = SqlDataSource2 
      childRepeater.DataBind() 
     End If 
    End Sub 

但是这显示了所有嵌套中继器不匹配,例如旅游,主题parentrepeater领域 的那些数据,dep7应该与孩子中继

+0

你可以使用两个嵌套中继器,就像本文:[在ASP.NET中使用嵌套中继器的快速指南](http://www.codeproject.com/KB/aspnet/AspNetNestedRepeaters.aspx) –

+0

hmm似乎它可以工作,我试图只写一个简单的if语句,检查e.row是否<>到e.row.index - 1列,那么它会做一个小计是完全关闭 – MyHeadHurts

+0

你会必须为包含小计的行动态生成HTML,对吧?我想这可能也会起作用,尽管我认为自动生成的HTML比嵌套的中继器(至少将所有的HTML保留在页面中)更混乱。 –

回答

0

首先,添加2类字段:

private int _subTotal; // Not sure what you're summing but you 
         // wrote subtotal in your pseudo-output 
private int _lastTourId; 

重置这些领域您数据绑定你的中继之前:

_subTotal = 0; 
_lastTourId = -1; 
TourRepeater.DataBind(); 

将创建一个单级中继器:

<asp:Repeater ID="TourRepeater" ...> 
    <HeaderTemplate>...<> 
    <ItemTemplate> 
    <tr> 
     Some columns with your tour data 
    </tr> 
    <PlaceHolder ID="SubTotalRow" ... /> 
    </ItemTemplate> 
    <FooterTemplate> 
    <PlaceHolder ID="SubTotalRow" ... /> 
    </FooterTemplate> 
</asp:Repeater> 

绑定此Repeater直接到你的旅游数据,然后做你的OnItemDataBound事件处理程序(我“将不得不去为C#):

void RepeaterItemDataBound(object source, RepeaterItemEventArgs e) 
{ 
    if (
    e.Item.ItemType == ListItemType.Item || 
    e.Item.ItemType == ListItemType.AlternatingItem // think you forgot this 
) 
    { 
    var tour = e.Item.DataItem as Tour; 
    if (tour != null) 
    { 
     if (_lastTourId == -1) { _lastTourId == tour.TourId; } // To avoid subtotal row before first tour 
     if (tour.TourId != _lastTourId) // This is a new tour so insert a subtotal row for the previous tour 
     { 
     var subTotalRow = e.Item.FindControl("SubTotalRow") as PlaceHolder; 
     if (subTotalRow != null) 
     { 
      RenderSummaryRow(subTotalRow, _subTotal); 
     } 
     _subTotal = tour.SomeValueYouWantToAddToSubTotal; 
     } 
     else 
     { 
     _subTotal += tour.SomValueYouWantToAddToSubTotal; 
     } 
     _lastTourId = tour.TourId; 
    } 
    } 
    else if (e.Item.ItemType == ListItemType.Footer) 
    { 
    var subTotalRow = e.Item.FindControl("SummaryRow") as PlaceHolder; 
    if (summaryTotalRow != null) 
    { 
     RenderSummaryRow(subTotalRow, _subTotal); 
    } 
    } 
} 

private void RenderSummaryRow(PlaceHolder placeHolder, int subTotal) 
{ 
      // create subtotal row manually by either creating TableRow + TableCells and adding them to a placeholder, or 
      // just add a literal and create your markup manually as innerHtml. Put your _subtotal value in where you want 
} 

的另一种方法是检索您的旅游数据转换成一个DataTable,并检索与ROLLUP等,这将创建和数据玛丽行自动。在网络上有几个关于这个的教程,但是在我切换到MVC之前,我找不到那个伟大的教程。

+0

嗯,我将它转换为vb.net并在这里得到一个错误 Dim Tour = TryCast(e.Item.DataItem,Tour) tour is没有定义 – MyHeadHurts

+0

对不起。 e.Item.DataItem在页脚中为空。请参阅修订后的代码,这也修复了小计计算中的错误。 – carlsb3rg

+0

是啊bt错误是在 Dim tour = TryCast(e.Item.DataItem,Tour) – MyHeadHurts