I controlli iterativi, come DataGrid, DataList e Repeater, si rivelano quasi indispensabili nella visualizzazione di report.
A renderli così attraenti è il meccanismo basato su template per generare l'interfaccia utente.
Talvolta si rende necessario annidare tra loro più controlli iterativi e questi casi richiedono qualche attenzione in più, specialmente nella registrazione dei gestori d'evento.
Prendiamo il semplice caso di due Repeater annidati.
<asp:Repeater id="ParentRepeater" runat="server" OnItemDataBound="ParentRepeater_ItemDataBound"> <HeaderTemplate> <table border="1"> <tr> <td><b>Company</b></td> </tr> </HeaderTemplate> <ItemTemplate> <tr> <td> <%# DataBinder.Eval(Container.DataItem, "ParentItem") %><br> <asp:Repeater id="CildrenRepeater" runat="server"> <HeaderTemplate> <table border="1" bgcolor="red"> <tr> <td><b>Employ</b></td> </tr> </HeaderTemplate> <ItemTemplate> <tr id="riga" runat="server"> <td><%# DataBinder.Eval(Container.DataItem, "CildrenItem") %></td> </tr> </ItemTemplate> <FooterTemplate> </table> </FooterTemplate> </asp:Repeater> </td> </tr> </ItemTemplate> <FooterTemplate> </table> </FooterTemplate> </asp:Repeater>
Nel codebehind:
private void Page_Load(object sender, System.EventArgs e) { if(!Page.IsPostBack) { //creo un nuovo data set myDataSet = new DataSet(); //creo la tabella padre MakeParentTable(); //credo la tabella dei figli MakeCildrenTable(); //associo il DataSet al repeater padre ParentRepeater.DataSource = myDataSet; //imposto il DataMember ParentRepeater.DataMember = "ParentTable"; //eseguo il bind ParentRepeater.DataBind(); } } public void ParentRepeater_ItemDataBound(Object Sender, RepeaterItemEventArgs e) { if(e.Item.ItemType == ListItemType.Item | e.Item.ItemType == ListItemType.AlternatingItem) { //recupero il riferimento al Repeater annidato Repeater tr = (Repeater)e.Item.FindControl("CildrenRepeater"); //recupero l'id del padre per filtrare i figli string parentID = ((DataRowView)e.Item.DataItem)[0].ToString(); //creo una vista sulla tabella dei figli DataView myDataView = myDataSet.Tables["CildrenTable"].DefaultView; //la filtro myDataView.RowFilter = "id = " + parentID; //l'associo come data surce tr.DataSource = myDataView; //registro il gestore dell'evento tr.ItemDataBound += new RepeaterItemEventHandler(tr_ItemDataBound); //eseguo il bind tr.DataBind(); } } private void tr_ItemDataBound(object sender, RepeaterItemEventArgs e) { if(e.Item.ItemType == ListItemType.Item | e.Item.ItemType == ListItemType.AlternatingItem) { //recupero il referimento alla riga della tabella System.Web.UI.HtmlControls.HtmlTableRow riga = (HtmlTableRow)e.Item.FindControl("riga"); //recupero il valore dal DataRowView string cildrenID = ((DataRowView)e.Item.DataItem)[0].ToString(); if(null != riga) { //imposto il colore if(cildrenID == "1")riga.BgColor = "white"; } } }
Una volta eseguite nel Page_Load le classiche operazioni di binding dei dati, nel gestore dell'evento ParentRepeater_ItemDataBound recuperiamo il riferimento al Repeater figlio, associamo i dati filtrati ed infine prima di eseguire il DataBind registriamo un gestore per l'evento ItemDataBound.
In questo esempio coloreremo la cella con id = 1, una decisione arbitraria usata per esempio, da sostituire con condizioni più adatte ad un contesto reale.
L'esempio è realizzato utilizzando due Repeater, ma le solite regole si applicano a qualsiasi tipo di controllo vogliate annidare.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.