web-dev-qa-db-fra.com

Répéteur en répéteur

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

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

Est-ce possible? Je pensais pouvoir le faire directement dans le fichier aspx comme:

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

42
bill

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 liez-le par les données.

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();
    }
}
77
Anton

J'ajouterais 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, implémentez-le:

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 du contrôle plutôt qu'au niveau ItemDataBound afin que, si vous devez supprimer des contrôles ou des éléments dans vos modèles, vous n'avez pas à vous soucier de la recherche de code dans les contrôles parents qui l'utilisent. Tout est localisé avec le contrôle de lui-même. De plus, vous n’avez jamais à faire une FindControl.

Si vous souhaitez remplacer un contrôle ultérieurement, vous pouvez simplement le supprimer et votre code fonctionnera toujours, car il est entièrement autonome. L'utilisation de ItemDataBound entraînerait la compilation de votre code, mais elle planterait ou agirait de manière inattendue au moment de l'exécution, en raison de sa dépendance à l'égard des contrôles enfants.

24
Kelsey

Voici comment c'est fait:

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

Ainsi, si vous connaissez la colonne de la table parent qui contient la table enfant/source de données pour le répéteur imbriqué, vous pouvez l'insérer directement dans le fichier aspx.

8
bill

Repeater1 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();
    }  
}
2
Ravi Ram

Si j'ai besoin de le faire, je le fais généralement en utilisant l'événement ItemDataBound du répéteur parent pour 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 aux données via e.Item.DataItem.

2
joelt
1
NiK
 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();
            }
    }
0
Lev Z