2010-01-19 18 views
6

Ho una origine oggetto che voglio associare a un ripetitore. il problema è che non riesco a capire come visualizzare una quantità variabile di colonne con una quantità variabile di righe.Colonne ripetitore variabile

ad esempio:

L'insieme di dati che ho è strutturato in questo modo. Objectdatasource è un List<item>.

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

itemdata { 
    DateTime year; 
    double amount; 
} 

in modo sostanzialmente voglio fare un tavolo

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

Il numero di elementi sono variabili, così come il numero di ItemData che l'oggetto contiene.

Spero che qualcuno possa indicarmi la giusta direzione.

Grazie

+0

Posso inserire un ripetitore annidato nel tag ? – Mike

risposta

6

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

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.

+1

Questa è una risposta brillante. Ha funzionato. Grazie mille. Penso di iniziare a vedere anche i ripetitori nidificati nel sonno. : P – Mike

0

ti suggerisco di convertire i dati in una nuova struttura di dati in questo modo:.

name_data { 
    string name; 
    int[] amounts; 
} 

Si potrebbe quindi vincolare il proprio ripetitore a un elenco (name_data>

per creare questa , per prima cosa, scorrere tra gli elenchi item e data e mantenere un elenco (probabilmente un Elenco) di tutti gli anni unici da riportare. Ordinare l'elenco risultante in modo che gli anni siano in ordine. Ora, gli indici della lista dell'anno correspongono ond ai numeri delle colonne nella tabella di output. Quindi, scorrere di nuovo l'elenco item, questa volta creando un nuovo oggetto name_data per ogni oggetto item. Il costruttore name_data sarà simile al seguente:

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

Il numero di anni è il numero di voci nell'elenco dell'anno.

Infine, passo attraverso la lista data per i item, cercare l'anno nell'elenco anno per ottenere l'indice, poi attaccare il valore importo nel campo quantità nel corrispondente amounts slot. Aggiungi il tuo name_data completato alla lista.

Una volta fatto, si dovrebbe essere in grado di legare la vostra lista name_data al ripetitore

+0

Non sono sicuro che la struttura avrebbe funzionato per lui. Nella sua struttura, può assegnare un importo per un anno nel mezzo in cui il vostro supporterà che tutti gli elementi avessero dati nell'ordine appropriato. –

+0

Sì, nella tua risposta, richiede che tutto sia in ordine e ordinato. Nel mio caso ci sono volte che non è in ordine. – Mike

+0

Questo è il motivo per cui ho suggerito un primo passaggio attraverso i dati per afferrare gli anni e ordinarli. Il secondo passaggio per assegnare i dati alla colonna corretta. – Ray

Problemi correlati