none
Repeater Imbriqués avec DataSource différents

    Question

  • Bonjour,

    Je cherche à afficher dynamiquement des données de ma base de données.

    Pour cela j’utilise un premier contrôle Repeater.

    Mes données proviennent de 2 requêtes différentes. Le résultat de la seconde requête dépend de la première (la requête 2 a besoin d’id généré par la requête 1).

    J’utilise donc un second Repeater imbriqué dans le 1 pour afficher le résultat de la requête 2.

    Le Repeater.DataSource de la requête 2 est donc différent de celui de la requete1.

    J’ai essayé ceci :

    protected void Page_Load(object sender, EventArgs e)
        {
            LoadMessage();
            if (!IsPostBack)
            {
                ParentRepeater.DataSource = LoadMessage();
                ParentRepeater.DataBind();
            }
        }
    
        protected DataTable LoadMessage()
        {
            DataTable dt = new DataTable();
            m = new Message();
            dt = m.GetMessage();
            return dt;
        }
    
        protected void ItemBound(object source, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                Repeater childRepeater = (Repeater)e.Item.FindControl("ChildRepeater");
    
                DataTable dt = new DataTable();
                dt = ParentRepeater.DataSource as DataTable;
    
                DataTable dtCategory;
                foreach (DataRow dr in dt.Rows)
                {
                    dtCategory = new DataTable();
                    dtCategory = m.GetCategoriesForMessage(Convert.ToInt32(dr["Id"]));
                    childRepeater.DataSource = dtCategory;
                }
                childRepeater.DataBind();
            }
        }

    Mon dtCategory contient les bonnes données, mais au final ce sont les données du premier enregistrement qui apparaissent pour tous les enregistrements.

    Comment puis-je faire pour que ce soit la bonne DataTable qui soit la DataSource?

    Merci pour votre aide.

     

    vendredi 18 avril 2014 16:28

Réponses

  • Il y a quelques modifications à faire :

    Supprimez OnItemDataBound dans le ChildRepeater.

    Ajoutez dans ItemBound1 un      

    childRepeater.DataSource = dtCategory;

    childRepeater.DataBind();

    Et le plus important, dans le code aspx du ParentRepeater, ajoutez

     <ItemTemplate>
                <div class="ContainerDate">
                         <asp:HiddenField ID="Id"   runat="server" Value='<%#DataBinder.Eval(Container.DataItem, "Id") %>' />
     
                    <%#DataBinder.Eval(Container.DataItem, "DatePublication") %>
                </div>
                <br />

    Bien cordialement,

     


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    • Marqué comme réponse paintbox00 lundi 28 avril 2014 16:07
    vendredi 25 avril 2014 06:41
    Propriétaire
  • Bonjour Aurel,

    merci pour votre aide.

    Je comprends votre explication mais j'ai du mal à la mettre en pratique.

    Voici ce que j'ai fait

     protected void ItemBound(object source, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                Repeater childRepeater = (Repeater)e.Item.FindControl("ChildRepeater");
             
                DataTable dtCategory = new DataTable();
    
                HiddenField hf_refId = (HiddenField)e.Item.FindControl("Id");
                int id = Convert.ToInt32(hf_refId.Value);
    
                dtCategory = m.GetCategoriesForMessage(id);
                childRepeater.DataSource = dtCategory;        
            }
        }

    ChildRepeater est mon repeater sur ma page html. Id est le champ que j'essaye de récupérer.

    Lorsque j'exécute mon application, j'ai un NullReferenceException sur  int id = Convert.ToInt32(hf_refId.Value); .

    J'ai beau instancié l'objet hf_refId ça ne change rien.

    J'ai également essayé de voir ce que contenait la DataSource source mais il semble vide.

    Pouvez-vous m'en dire plus.

    Merci

    • Marqué comme réponse paintbox00 lundi 28 avril 2014 16:07
    mardi 22 avril 2014 20:41

Toutes les réponses

  • Bonjour

    L'évènement ItemBound est appelé pour chaque ligne créé pour le Repeater parent.
    Donc pour chaque exécution d’ItemBound vous parcourez la dataSource et bindez le Repeater enfant avec toutes les valeurs possibles. A la fin, il reste une seule, la dernière.
    La solution sera de ne pas parcourir toute la DataTable parent, mais de récupérer le Id et l'utiliser.
    Sans savoir exactement votre code, j'essaye de deviner :

    HiddenField hf_resID = (HiddenField)e.Item.FindControl("ChampIdLigne"); int temResID = Convert.ToInt32(hf_resID.Value);

    dtCategory = new DataTable();
                    dtCategory
    = m.GetCategoriesForMessage(temResID );
                    childRepeater
    .DataSource = dtCategory;

    Bien cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    mardi 22 avril 2014 05:52
    Propriétaire
  • Bonjour Aurel,

    merci pour votre aide.

    Je comprends votre explication mais j'ai du mal à la mettre en pratique.

    Voici ce que j'ai fait

     protected void ItemBound(object source, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                Repeater childRepeater = (Repeater)e.Item.FindControl("ChildRepeater");
             
                DataTable dtCategory = new DataTable();
    
                HiddenField hf_refId = (HiddenField)e.Item.FindControl("Id");
                int id = Convert.ToInt32(hf_refId.Value);
    
                dtCategory = m.GetCategoriesForMessage(id);
                childRepeater.DataSource = dtCategory;        
            }
        }

    ChildRepeater est mon repeater sur ma page html. Id est le champ que j'essaye de récupérer.

    Lorsque j'exécute mon application, j'ai un NullReferenceException sur  int id = Convert.ToInt32(hf_refId.Value); .

    J'ai beau instancié l'objet hf_refId ça ne change rien.

    J'ai également essayé de voir ce que contenait la DataSource source mais il semble vide.

    Pouvez-vous m'en dire plus.

    Merci

    • Marqué comme réponse paintbox00 lundi 28 avril 2014 16:07
    mardi 22 avril 2014 20:41
  • Dans le premier Repeater, vous devez ajouter un contrôle de type Hidden qui en effet est le lien entre les deux Repeater. Il aura le nom Id et la valeur qui se trouve sur la colonne Id dans le premier DataSet. 
    Si vous pouvez nous montrer le code ASPX on pourra l'adapter pour vous.

    Bien cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    jeudi 24 avril 2014 07:16
    Propriétaire
  • Bonjour,

    voici le code de la page aspx:

    <%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true"

    CodeFile="Default.aspx.cs" Inherits="_Default" %> <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server"> </asp:Content> <asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder2" runat="Server"> <asp:Repeater ID="ParentRepeater" runat="server" OnItemDataBound="ItemBound1"> <ItemTemplate> <div class="ContainerDate"> <%#DataBinder.Eval(Container.DataItem, "DatePublication") %> </div> <br /> <div class="Tag ClearBlock"> Tag: <asp:Repeater ID="ChildRepeater" runat="server" OnItemDataBound="ItemBound2"> <ItemTemplate> <div class="Tag"><%#DataBinder.Eval(Container.DataItem, "CategoryName") %></div> </ItemTemplate> </asp:Repeater> </div> <div class="ContainerMessage"> <div class="MessageTitle"> <asp:Label ID="LabTitle" class="LabTitle" runat="server" Text='<%#DataBinder.Eval(Container.DataItem, "Title") %>'></asp:Label> </div> <!--<hr />--> <p class="MessageTexte"><%#DataBinder.Eval(Container.DataItem, "Text") %></p> </div> </ItemTemplate> </asp:Repeater> </asp:Content> <asp:Content ID="Content4" ContentPlaceHolderID="ContentPlaceHolder4" runat="Server"> <p>D.G. 2014</p> </asp:Content>

    Merci pour votre aide

    jeudi 24 avril 2014 16:16
  • Il y a quelques modifications à faire :

    Supprimez OnItemDataBound dans le ChildRepeater.

    Ajoutez dans ItemBound1 un      

    childRepeater.DataSource = dtCategory;

    childRepeater.DataBind();

    Et le plus important, dans le code aspx du ParentRepeater, ajoutez

     <ItemTemplate>
                <div class="ContainerDate">
                         <asp:HiddenField ID="Id"   runat="server" Value='<%#DataBinder.Eval(Container.DataItem, "Id") %>' />
     
                    <%#DataBinder.Eval(Container.DataItem, "DatePublication") %>
                </div>
                <br />

    Bien cordialement,

     


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    • Marqué comme réponse paintbox00 lundi 28 avril 2014 16:07
    vendredi 25 avril 2014 06:41
    Propriétaire
  • Bonjour

    Un petit retour?

    Bien cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    lundi 28 avril 2014 06:30
    Propriétaire
  • Bonjour,

    oui merci cela fonctionne.

    Voici exactement ce qu'il fallait mettre (si cela peut aider quelqu'un d'autre):

    les 2 repeater imbriqués

    <asp:Repeater ID="ParentRepeater" runat="server" OnItemDataBound="ItemBound">
            <ItemTemplate>
              
                <div class="Tag Clear">
                    Tag:
                    <asp:Repeater ID="ChildRepeater" runat="server">
                        <ItemTemplate>
                            <span ><%#DataBinder.Eval(Container.DataItem, "CategoryName") %></span>
                        </ItemTemplate>
                    </asp:Repeater>
                </div>
    
            </ItemTemplate>
        </asp:Repeater>

    et ..

    protected void ItemBound(object source, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                Repeater childRepeater = (Repeater)e.Item.FindControl("ChildRepeater");
    
                HiddenField hf_resID = (HiddenField)e.Item.FindControl("Id");
                int ID = Convert.ToInt32(hf_resID.Value);
    
                DataTable dtCategory = new DataTable();
    
                dtCategory = m.GetCategoriesForMessage(ID);
                childRepeater.DataSource = dtCategory;
                childRepeater.DataBind();
            }
        }

    Cela fonctionne parfaitement.

    Encore un grand merci pour votre aide !

    lundi 28 avril 2014 16:06