可变中继器列

Mik*_*ike 6 asp.net data-binding repeater

我有一个objectdatasource,我想绑定到转发器.问题是,我无法弄清楚如何显示具有可变行数的可变数量的列.

例如:

我的数据集结构如下.objectdatasource是一个List<item>.

item {
  string name;
  List<itemdata> data;
}

itemdata {
  DateTime year;
  double amount;
}
Run Code Online (Sandbox Code Playgroud)

所以基本上我想做一张桌子

      |  year  |  year  |  year  |  year
 name | amount | amount | amount | amount
 name | amount | amount | amount | amount
 name | amount | amount | amount | amount
 name | amount | amount | amount | amount
Run Code Online (Sandbox Code Playgroud)

项目数量是可变的,以及项目包含的项目数据的数量.

希望有人能指出我正确的方向.

谢谢

Ben*_*der 7

您的问题的解决方案将需要三个不同的中继器,其中一个嵌套在另一个中.从这样的标记开始.

  <table>
       <tr class="headerRow">
          <td> &nbsp;</td>
          <asp:Repeater ID="rptYearHeader" runat="server" OnItemDataBound="rptYearHeader_ItemDataBound">
              <ItemTemplate>
                 <td class="header"><asp:Literal ID="litYear" runat="server"></asp:Literal></td>
              </ItemTemplate>
          </asp:Repeater>
       </tr>
       <asp:Repeater ID="rptName" runat="server" ItemDataBound="rptName_ItemDataBound">
          <ItemTemplate>
             <tr>
                <td><asp:Literal ID="litName" runat="server"></asp:Literal></td>
                <asp:Repeater ID="rptAmounts" runat="server" OnItemDataBound="rptAmounts_ItemDataBound">
              <ItemTemplate>
                 <td><asp:Literal ID="litAmount" runat="server"></asp:Literal></td>
              </ItemTemplate>
          </asp:Repeater>
             </tr>
          </ItemTemplate>
       </asp:Repeater>
    </table>
Run Code Online (Sandbox Code Playgroud)

绑定到这可能有点棘手.我们的想法是,首先绑定标题行 - 然后我们绑定数据行和列.您将需要使用OnItemDataBound事件通过代码处理数据绑定,以便您可以使用必要的数据连接嵌套的转发器.

首先,我们将标题行绑定到Years.您需要隔离数据源中存在的唯一年份集合,并将其保存在私有变量中.稍后您将需要在其他中继器的数据绑定期间访问它.这将作为标题行的数据源,为每年创建一个单元格/列.

List<DateTime> _Years =  dataSource.SelectMany(x => x.data).GroupBy(y => y.Year);
rptYear.DataSource = _Years;
rptYear.DataBind();
Run Code Online (Sandbox Code Playgroud)

现在,您需要将Name转发器与原始数据源绑定.就像是

rptName.DataSource = dataSource;
rptName.DataBind();
Run Code Online (Sandbox Code Playgroud)

这将为列表中的每个项目创建一行.

在此转发器的OnItemDataBound事件期间,您需要将嵌套转发器绑定到会计年度列表 - 我们的_Years变量中每个会计年度一个 - 与当前行的数据项中的任何适用数据.这有点棘手,但我会试着解释一下:

protected void rptName_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
// get the data item being bound
item currentItem = e.Item.DataItem as item;

// bind the item's name to the literal
//...
//

// get a list of amounts to bind to the nested repeater
// because we cant be sure that every item has amount for all years
// we create a list that we know has all years and plug in the items 
// data accordingly.

    List<double> amounts = new List<double>();
     for (int i = 0; i < _Years.Count; i++)
     {
        // check whether the current item has data for the year
        dataItem di = currentItem.data.Where(d => d.Year == _Years[i]).FirstOrDefault();

        if(di == null)
        {
             // the year did not exist, so we add an amount of 0 
             amounts.Add(0);
        }
        else
        {
           // the year did exist, so we add that year's amount
           amounts.Add(di.amount);
        }
     }

     // we now have a list of amounts for all possible years, with 0 filling in
     // where the item did not have a value for that year

     // bind this to the nested repeater
     rptAmounts.DataSource = amounts;
     rptAmounts.DataBind();

}
Run Code Online (Sandbox Code Playgroud)

祝好运.

我不得不使用多个嵌套中继器来完成以下子总计和总计行.我开始在睡梦中看到嵌套的中继器.