2010-05-27 6 views
39

J'ai un répéteur à l'intérieur d'un répéteur. Où le répéteur parent est lié à un Datatble qui a une colonne avec un Datatable dedans.Répéteur dans le répéteur

Je voudrais lier le répéteur enfant à la colonne datatable dans le datarow du répéteur parent

Est-ce possible? Je pensais que je pouvais le faire directement dans le fichier aspx comme:

DataSource="<%# DataBinder.Eval(Container.DataItem, "Products")%>" mais cela ne semble pas fonctionner.

Répondre

70

Dans le répéteur parent, attachez une méthode à l'événement OnItemDataBound et dans la méthode, recherchez le répéteur imbriqué et les données le lient.

Exemple (.aspx):

<asp:Repeater ID="ParentRepeater" runat="server" OnItemDataBound="ItemBound"> 
    <ItemTemplate> 
     <!-- Repeated data --> 
     <asp:Repeater ID="ChildRepeater" runat="server"> 
      <ItemTemplate> 
       <!-- Nested repeated data --> 
      </ItemTemplate> 
     </asp:Repeater> 
    </ItemTemplate> 
</asp:Repeater> 

Exemple (.cs):

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!IsPostBack) 
    { 
     ParentRepeater.DataSource = ...; 
     ParentRepeater.DataBind(); 
    } 
} 

protected void ItemBound(object sender, RepeaterItemEventArgs args) 
{ 
    if (args.Item.ItemType == ListItemType.Item || args.Item.ItemType == ListItemType.AlternatingItem) 
    { 
     Repeater childRepeater = (Repeater)args.Item.FindControl("ChildRepeater"); 
     childRepeater.DataSource = ...; 
     childRepeater.DataBind(); 
    } 
} 
+0

trouve toujours bizarre quand ItemDataBound est utilisé pour cela. Y at-il une raison pour laquelle vous ne le faites pas au niveau du contrôle? – Kelsey

+0

@Kelsey - cela a toujours fonctionné pour moi. Aucune raison de le faire autrement. – Anton

+1

Voir ma réponse pour certains avantages à l'utilisation de l'événement de contrôle 'DataBinding' à la place. :) – Kelsey

2

Si je dois le faire, je le fais habituellement à l'aide de l'événement ItemDataBound du répéteur de parent lier le répéteur enfant. Si e est votre paramètre EventArgs, vous aurez accès au répéteur enfant via e.Item.FindControl(), et l'accès aux données via e.Item.DataItem.

20

Je voudrais ajouter un événement DataBinding au répéteur enfant lui-même:

<asp:Repeater ID="parentRepeater" runat="server"> 
    <asp:Repeater ID="childRepeater" runat="server" 
     OnDataBinding="childRepeater_DataBinding" /> 
</asp:Repeater> 

Ensuite, il suffit la mettre en oeuvre:

protected void childRepeater_DataBinding(object sender, System.EventArgs e) 
{ 
    Repeater rep = (Repeater)(sender); 

    int someIdFromParentDataSource = (int)(Eval("ParentID")); 

    // Assuming you have a function call `GetSomeData` that will return 
    // the data you want to bind to your child repeater. 
    rep.DataSource = GetSomeData(int); 
    rep.DataBind(); 
} 

Je préfère le faire au niveau de contrôle au lieu du niveau ItemDataBound si Si vous devez supprimer des contrôles ou des éléments dans vos modèles, vous n'avez pas à vous soucier de rechercher du code dans les contrôles parents qui l'utilisent. Tout se localise avec le contrôle lui-même. De plus, vous n'avez jamais à faire un FindControl.

Si vous souhaitez remplacer un contrôle dans le futur, vous pouvez simplement le supprimer et votre code fonctionnera car il est entièrement autonome. L'utilisation de ItemDataBound entraînerait la compilation de votre code, mais il planterait ou fonctionnerait de façon inattendue à l'exécution en raison de sa dépendance aux contrôles enfants.

+0

afin que vous ajoutiez un événement de liaison de données au répéteur enfant? et comment puis-je obtenir la source de données ?? qui est à nouveau une ligne de type pouvant être datée à partir de la source de données du contrôle parent? Merci! – bill

+0

@bill De quelles informations avez-vous besoin dans la source de données parent pour obtenir votre nouvelle source de données? Vous avez accès à toutes les informations sur les lignes actuelles via la fonction 'Eval'. Je vais mettre à jour ma réponse pour montrer un exemple. – Kelsey

+0

la source de données parente est datatable et contient une colonne qui est elle-même datable. À la liaison de la source de données enfant est dans la source de données parent .. c'est pourquoi je pensais que je pouvais simplement lier dans le fichier ASPX – bill

7

Voici comment faire:

DataSource='<%# ((System.Data.DataRowView)Container.DataItem)[3] %>' 

Donc, si vous connaissez la colonne dans la table parent qui contient la table des enfants/source de données pour le répéteur imbriqué, vous pouvez le mettre directement dans le fichier aspx.

2

Repeater1 événement OnItemDataBound, puis FindControl Repeater2. Le code-behind ne trouvera pas le Repeater2 imbriqué! Vous devez utiliser FindControl ("Repeater2").

protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 
    if (e.Item.DataItem != null) 
    { 
     MemberView dataRow = (MemberView)e.Item.DataItem; 
     var cat = MemberPresenter.getMemberID(dataRow.memID); 

     Repeater rp2 = (Repeater)e.Item.FindControl("Repeater2"); 
     rp2.DataSource = cat; 
     rp2.DataBind(); 
    } 
} 
0
protected void MainRepeater_ItemDataBound(object sender, RepeaterItemEventArgs args) 
    { 
     if (args.Item.ItemType == ListItemType.Item || args.Item.ItemType == ListItemType.AlternatingItem) 
      { 
       Repeater childRepeater = (Repeater)args.Item.FindControl("ChildRepeater"); 

       DataTable innerTable= ((DataRowView)args.Item.DataItem)["InnerTableColumnName"] as DataTable; 
       childRepeater.DataSource = tasksDetails; 
       childRepeater.DataBind(); 
      } 
    }