La soluzione al vostro problema richiederà tre diversi ripetitori, uno dei quali è annidato all'interno di un'altra. Inizia con il markup come questo.
<table>
<tr class="headerRow">
<td> </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>
Il collegamento a questo può essere un po 'complicato. L'idea è, prima leghiamo la riga di intestazione - quindi leghiamo le righe di dati e attraverso le colonne. Si vorrà gestire l'associazione dei dati tramite il codice sottostante utilizzando l'evento OnItemDataBound in modo da poter collegare il ripetitore annidato con i dati necessari.
Prima leghiamo la riga di intestazione con Anni. È necessario isolare una raccolta di anni unici presenti nell'origine dati e conservarla in una variabile privata. Sarà necessario accedervi durante l'associazione dei dati degli altri ripetitori più tardi. Questo servirà come origine dati per la riga di intestazione, creando una cella/colonna per ogni anno.
List<DateTime> _Years = dataSource.SelectMany(x => x.data).GroupBy(y => y.Year);
rptYear.DataSource = _Years;
rptYear.DataBind();
Ora è necessario associare il ripetitore Nome all'origine dati originale. Qualcosa come
rptName.DataSource = dataSource;
rptName.DataBind();
Questo creerà una riga per ogni articolo nel tuo elenco.
Durante l'evento OnItemDataBound per questo ripetitore, è necessario associare il ripetitore annidato a un elenco di anni fiscali, uno per ogni anno fiscale nella variabile _Sieni, con tutti i dati applicabili dall'elemento di dati della riga corrente. Questo diventa un po 'complicato, ma cercherò di spiegare:
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();
}
Buona fortuna.
Ho dovuto estrarre questo con più ripetitori annidati per le righe totale parziale e totale parziale prima. Ho iniziato a vedere ripetitori nidificati nel sonno.
Posso inserire un ripetitore annidato nel tag? –
Mike