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.

<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.