Meilleur auteur de réponses
Comment imbriquer une DataList dans un Repeater ?

Question
-
Prenons comme exemple la base de données Northwind, et précisément les produits, et les catégories auxquelles ils appartiennent.
Je voudrais afficher les produits, groupés par catégorie. À la page http://www.c-sharpcorner.com/uploadfile/Mike%20Clark/using%2Dweb%2Duser%2Dcontrols%2Din%2Drepeaters%2Dand%2Ddatalist/, Mike Clark propose une solution basée sur des données XML. Il utilise un Repeater pour balayer les catégories, et une DataList pour afficher les produits de la catégorie courante.
Je voudrais faire la même chose, sauf que mes données sont construites dynamiquement dans un objet List(Of produit), où produit contient aussi le libellé de la catégorie. Comment faire pour que la DataList filtre sur la catégorie courante prise en compte par le Repeater ?
Si besoin, je peux bien sûr transformer ma structure à plat en une structure à deux niveaux : un objet List(Of catégorie), où catégorie contient un objet List(Of produit). Ma question reste identique.
Merci d'avance,
Gilbert
- Modifié Gilbert Tordeur jeudi 8 décembre 2011 14:56
Réponses
-
Bonjour,
Vous pouvez utiliser deux contrôles Repeater imbriqués et utiliser l’événement OnItemDataBound du Repeater conteneur afin de approvisionner le Repeater des produits.
Il faut que mettiez en place une collection d'objets catégories (IList<Category> par exemple). Cette collection doit contenir la liste unique des catégories et chaque catégorie possède ses propriétés ainsi qu'une collection de produits (IList<Product> par exemple).
Vous pouvez construite cette collection facilement avec une requête LINQ par exemple mais il y a bien sûr plusieurs façons de le faire.
Quand vous aurez mis en place cette collection, vous devez effectuer un binding du repeater conteneur (rp.DataSource = l; rpt.DataBind();) à l'emplacement que vous désirez dans le code. Il faut bien sûr mettre les champs qu'il faut dans le Repeater côté ASP (Databinder.Eval ...) ou C#(ItemDataBound ...).
Ensuite dans l’événement OnItemDataBound du Repeater conteneur, vous devez récupérer le Repeater des produits avec la fonction e.Item.FindControl("rptProducts") et l'objet Category ((Category)e.Item.DataItem) puis effectuez le binding (rp.DataSource = c.Products; rpt.DataBind()). Il faut bien sûr mettre les champs qu'il faut dans le composant côté ASP ou C#. Cette opération doit être effectuée sur tous les éléments de type "donnée", pour cela vous devez ajouter un test au début de la méthode de l'événement (if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {/* ... */ } ).
Pour plus d'information sur l'événement OnItemDataBound, je vous invite à lire la documentation MSDN.
Cordialement,
aelassas.free.fr- Proposé comme réponse Ciprian Duduiala vendredi 9 décembre 2011 08:02
- Marqué comme réponse Gilbert Tordeur vendredi 9 décembre 2011 10:51
- Modifié Link.frEditor samedi 10 décembre 2011 02:50 Modification mineure.
Toutes les réponses
-
Bonjour,
Vous pouvez utiliser deux contrôles Repeater imbriqués et utiliser l’événement OnItemDataBound du Repeater conteneur afin de approvisionner le Repeater des produits.
Il faut que mettiez en place une collection d'objets catégories (IList<Category> par exemple). Cette collection doit contenir la liste unique des catégories et chaque catégorie possède ses propriétés ainsi qu'une collection de produits (IList<Product> par exemple).
Vous pouvez construite cette collection facilement avec une requête LINQ par exemple mais il y a bien sûr plusieurs façons de le faire.
Quand vous aurez mis en place cette collection, vous devez effectuer un binding du repeater conteneur (rp.DataSource = l; rpt.DataBind();) à l'emplacement que vous désirez dans le code. Il faut bien sûr mettre les champs qu'il faut dans le Repeater côté ASP (Databinder.Eval ...) ou C#(ItemDataBound ...).
Ensuite dans l’événement OnItemDataBound du Repeater conteneur, vous devez récupérer le Repeater des produits avec la fonction e.Item.FindControl("rptProducts") et l'objet Category ((Category)e.Item.DataItem) puis effectuez le binding (rp.DataSource = c.Products; rpt.DataBind()). Il faut bien sûr mettre les champs qu'il faut dans le composant côté ASP ou C#. Cette opération doit être effectuée sur tous les éléments de type "donnée", pour cela vous devez ajouter un test au début de la méthode de l'événement (if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {/* ... */ } ).
Pour plus d'information sur l'événement OnItemDataBound, je vous invite à lire la documentation MSDN.
Cordialement,
aelassas.free.fr- Proposé comme réponse Ciprian Duduiala vendredi 9 décembre 2011 08:02
- Marqué comme réponse Gilbert Tordeur vendredi 9 décembre 2011 10:51
- Modifié Link.frEditor samedi 10 décembre 2011 02:50 Modification mineure.
-
Akram,
Merci beaucoup pour ta réponse ; j'ai pu la mettre en oeuvre et cela fonctionne.
Pour d'autres lecteurs qui seraient intéressés, voici le code utilisé. Le niveau supérieur des données représente les options d'un programme. Le niveau inférieur représente la valeur de l'option pour chaque identifiant.
<asp:Repeater ID="RptOptionProgramme" runat="server" OnItemDataBound="RptOptionProgramme_OnItemDataBound"> <ItemTemplate> <h1><%# DataBinder.Eval(Container.DataItem, "Description")%></h1> <asp:Repeater ID="RptValeur" runat="server"> <ItemTemplate> <%# DataBinder.Eval(Container.DataItem, "NomIdentifiant")%> : <%# DataBinder.Eval(Container.DataItem, "Valeur")%> <br /> </ItemTemplate> </asp:Repeater> </ItemTemplate> </asp:Repeater>
RptOptionProgramme.DataSource = Programme.GetInstanceAvecParametreOptionAutorisation(CjcApplication.NomProgramme).OptionProgrammes RptOptionProgramme.DataBind() Protected Sub RptOptionProgramme_OnItemDataBound(ByVal Sender As Object, ByVal e As RepeaterItemEventArgs) If (e.Item.ItemType = ListItemType.Item) OrElse (e.Item.ItemType = ListItemType.AlternatingItem) Then Dim RptValeurCourant = DirectCast(e.Item.FindControl("RptValeur"), Repeater) Dim OptionCourant = DirectCast(e.Item.DataItem, OptionProgramme) RptValeurCourant.DataSource = OptionCourant.AutorisationOptionProgrammes RptValeurCourant.DataBind() End If End Sub
Cordialement,Gilbert
-
Bonjour Gilbert,
merci d'avoir partagé la solution que vous avez mise en place.
Cordialement
- Modifié nikhoModerator vendredi 9 décembre 2011 12:39