Repeater Column Variables

I have an objectdatasource that I want to associate with a repeater. The problem is that I cannot figure out how to display a variable sum of columns with a variable number of rows.

eg:

The data set that I have is structured this way. The object data source is a List<item> .

 item { string name; List<itemdata> data; } itemdata { DateTime year; double amount; } 

so basically i want to make a table

  | year | year | year | year name | amount | amount | amount | amount name | amount | amount | amount | amount name | amount | amount | amount | amount name | amount | amount | amount | amount 

The number of elements is a variable, as well as the number of data elements that an element contains.

Hope someone can point me in the right direction.

thanks

+6
data-binding repeater
source share
2 answers

Solving your problem will require three different repeaters, one of which is nested inside the other. Start with this markup.

  <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> 

Attachment to this can be a bit complicated. The idea is that we first bind the header row and then bind the data rows and columns. You will want to handle the data binding using the code behind, using the OnItemDataBound event, so that you can attach a nested relay with the necessary data.

First, we associate the title bar with Years. You need to select a collection of unique years present in your data source and store it in a private variable. You will need to access it while linking the data of other repeaters later. This will serve as a data source for the title bar, creating one cell / column for each year.

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

Now you need to associate the Name repeater with the original data source. Something like

 rptName.DataSource = dataSource; rptName.DataBind(); 

This will create one line for each item in your list.

During the OnItemDataBound event for this repeater, you need to bind the nested repeater to the list of fiscal years — one for each fiscal year in our _Years variable — with any applicable data from the current row data item. This is a bit complicated, but I will try to explain:

 protected void rptName_ItemDataBound(object sender, RepeaterItemEventArgs e) { // get the data item being bound item currentItem = e.Item.DataItem as item; // bind the item 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 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(); } 

Good luck.

I had to defer this with a few nested repeaters for totals and large totals rows. I began to see nested repeaters in a dream.

+6
source share

I suggest you convert your data to a new data structure, for example:

 name_data { string name; int[] amounts; } 

Then you associate the repeater with List (name_data>.

To create this, first go through the item and data lists and save a list (possibly a list) of all the unique years that you need to report. Sort the resulting list so that the years are in order. The year list indices now correspond to the column numbers in your output table. Then iterate through the item list, this time creating a new name_data object for each item object. The name_data constructor will look like this:

 public name_data(string name, int yearCount) { this.name = name; amounts = new int[yearCount]; } 

YearCount is the number of items in the list.

Finally, go to the data list for the current item , find the year in the year list to get the index, then insert the amount in the quantity field in the corresponding amounts slot. Add the filled data_name to the list.

Once you are done, you can bind your name_data list to your relay

0
source share

All Articles