Accessing a parent repeater DataItem from a nested repeater

140 Views Asked by At

I'm trying to access a DataItem of a parent repeater from a nested repeater, but I keep getting blanks/nothing returned.

Basic Example:

<asp:Repeater ID="Products">
    <ItemTemplate>
        <%# Eval("product_name") %>
        <asp:Repeater ID="SubProducts">
            <ItemTemplate>
                <%# DataBinder.Eval(Container.Parent.Parent, "DataItem.product_name")%>
                <%# Eval("subproduct_name")
            </ItemTemplate>
        </asp:Repeater>
    </ItemTemplate>
</asp:Repeater>

Formats I've tried:

<%# DataBinder.Eval(Container, "NamingContainer.NamingContainer.DataItem.MyRepeaterDataItem")%>

<%# DataBinder.Eval(Container.Parent.Parent, "DataItem.prod_name")%>

I've also tried replacing NamingContainer.NamingContainer with Parent.Parent in each of the above.

These were similar topics that didn't work for me:

How to read a dataitem from a parent repeater?

How to access Parent repeater id from code behind (though I don't want to access from code behind)

1

There are 1 best solutions below

0
Albert D. Kallal On

Hum, what you have should work.

However, it WILL depend on how your binding (feeding) the data to the parent repeater. For example, if you feed the repeater a "reader", then for each row data bind, then "data item" does not exist.

so, for example, this works for me:

We have some hotels, and for EACH hotel, we list the booked people.

enter image description here

<asp:Repeater ID="Repeater1" runat="server" 
    OnItemDataBound="Repeater1_ItemDataBound">
    <ItemTemplate>
        <h3><%# Eval("HotelName") %> </h3>
        <h4><%# Eval("Description") %> </h4>

        <h4>Booked people in Hotel</h4>
        <asp:Repeater ID="Repeater2" runat="server">
            <ItemTemplate>
                Name: <%# Eval("FirstName") %> <%# Eval("LastName") %>
                <br />
                Show parent HotelName:
                <%# DataBinder.Eval(Container.Parent.Parent, "DataItem.HotelName")%> 
                <br />
            </ItemTemplate>
        </asp:Repeater>
        <hr />
    </ItemTemplate>
</asp:Repeater>

I am quite sure the data source being feed has to be inumerable.

Code beind:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadData();
    }


    void LoadData()
    {
        string strSQL =
            "SELECT * FROM tblHotelsA ORDER BY HotelName";
        DataTable rstData = General.MyRst(strSQL);

        Repeater1.DataSource= rstData;
        Repeater1.DataBind();

    }

And the row data bound for the main (parent repeater) is this:

    protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item ||
            e.Item.ItemType == ListItemType.AlternatingItem)
        {
            DataRowView rData = (DataRowView)e.Item.DataItem;
            string HotelID = rData["ID"].ToString();
            string strSQL = $"SELECT * FROM People WHERE Hotel_ID = {HotelID}";

            Repeater rNested = e.Item.FindControl("Repeater2") as Repeater;
            rNested.DataSource = General.MyRst(strSQL);
            rNested.DataBind();
        }
    }

My "general" helper routine (MyRst) just returns a data table, and that was this:

public static DataTable MyRst(string strSQL, string sConn = "")
{
    DataTable rstData = new DataTable();

        if (sConn == "")
            sConn = Properties.Settings.Default.TEST4;

    using (SqlConnection conn = new SqlConnection(sConn))
    {
        using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
        {
            cmdSQL.Connection.Open();
            rstData.Load(cmdSQL.ExecuteReader());
        }
    }
    return rstData;
}

So, what you have looks ok, but it will depend on HOW you filling out the main repeater.

Note how in the row data bind event, I have BOTH the repeater row AND ALSO the full data row - including columns that are NOT displayed in the repeater1.

That FULL data row (DataRowView) is ONLY available during the binding process, and THEN goes out of scope once data binding is complete. And if you feed a listview, gridview, or repeater a "reader" which is allowed? then as noted, the repeater will work, but the DatarowView item does not exist during the binding (row) event.