views:

349

answers:

5

I have a repeater inside a repeater. Where the parent repeater is bound to a Datable which has a column with a Datatable in it.

I would like to bind the child repeater to the datatable column in the parent repeater's datarow

Is this possible? i was thinking i could do this directly in the aspx file like:

DataSource="<%# DataBinder.Eval(Container.DataItem, "Products")%>" but it doesn't seem to work.

+8  A: 

In the parent repeater, attach a method to the OnItemDataBound event and in the method, find the nested repeater and data bind it.

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

Example (.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)
    {
        Repeater childRepeater = (Repeater)args.Item.FindControl("ChildRepeater");
        childRepeater.DataSource = ...;
        childRepeater.DataBind();
    }
}
Anton
@Anton Always find it odd when ItemDataBound is used for this. Is there any reason why you don't do it at the control level?
Kelsey
@Kelsey - this has always worked for me. No reason to do it otherwise.
Anton
@Anton see my answer for some advantages to using the controls `DataBinding` event instead. :)
Kelsey
+2  A: 

If I need to do that, I usually do it using the ItemDataBound event of the parent repeater to bind the child repeater. If e is your EventArgs parameter, you'll have access to the child repeater via e.Item.FindControl(), and access to the data via e.Item.DataItem.

joelt
+1  A: 

I would add a DataBinding event to the repeater itself:

<asp:Repeater ID="yourRepeater" runat="server" OnDataBinding="yourRepeater_DataBinding">

Then just implement it:

protected void yourRepeater_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();
}

I prefer to do it at the control level instead of the ItemDataBound level so that if you ever have to remove controls or items within your templates you don't have to worry about looking for code in the parent controls that use it. It get's all localize witht he control itself. Plus you never have to do a FindControl.

If you want to replace a control in the future you can just delete it and your code will still work since it is all self contained. Using the ItemDataBound would cause your code to still compile but crash or act unexpectedly at runtime because of it's reliance on child controls.

Kelsey
so you add a databinding event to the child repeater?and how do i get the datasource?? which again is a row of type datatable from the parent control's datasource? thanks!
bill
@bill What information do you need from the parent datasource to get your new datasource? You have access to all the current rows information via the `Eval` function. I will update my answer to show an example.
Kelsey
the parent datasource is a datatable and it has a column in it that is a datable itself. At binding the child datasource is IN the parent datasource.. which is why i was thinking i could just bind in the ASPX file
bill
@bill You could try `rep.DataSource = (DataTable)(Eval("yourColumnWithTableInIt"))`. You have to be able to get the `DataTable` out of your original DataSource.
Kelsey
+1  A: 

Hi, Here is an example of how to do this. Artile for nested repeater control

NiK
+1  A: 

here is how it's done:

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

so if you know the column in the parent table that holds the child table/datasource for the nested repeater you can put this directly in the aspx file

bill