嵌套转发器显示与父转发器匹配的数据

时间:2011-03-15 15:58:19

标签: asp.net vb.net repeater

我正在使用转发器来构建自定义表。但是,如果下一行巡视与前一行不匹配,我无法弄清楚如何使表显示小计。

类似的东西。

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字段匹配的数据 例如tour,theme,dep7应该在子中继器中匹配

1 个答案:

答案 0 :(得分: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中,并检索WITH ROLLUP等数据,这将自动创建汇总行。网上有几个关于这方面的教程,但是在我切换到MVC之前,我找不到一个很好用的。