2
votes

I'm beginning with ASP.NET and I'm wondering, if there is any "smart" way of displaying data from DataTable in groups?
Imagine following example: I get data from SQL to datatable grouped and sorted alredy:

protected void Page_Load(object sender, EventArgs e)
{
    DataTable dt = new DataTable();
    dt.Columns.Add("parent", typeof(string));
    dt.Columns.Add("child", typeof(string));
    dt.Rows.Add("AAA", "111");
    dt.Rows.Add("AAA", "222");
    dt.Rows.Add("AAA", "333");
    dt.Rows.Add("BBB", "444");
    dt.Rows.Add("BBB", "555");
    dt.Rows.Add("CCC", "666");
    dt.Rows.Add("CCC", "777");
    dt.Rows.Add("CCC", "888");

    repeaterParent.DataSource = dt;
    repeaterParent.DataBind();
}

and I want to display them on page like below:
enter image description here

I've tried to use nested repeaters for that:

<asp:Repeater ID="repeaterParent" runat="server">
    <ItemTemplate>
        <b><%# DataBinder.Eval(Container.DataItem, "parent") %></b>
        <br /> 
        <asp:repeater id="repeaterChild" runat="server">
            <itemtemplate>
                    - <%# DataBinder.Eval(Container.DataItem, "child") %> <br />
            </itemtemplate>
        </asp:repeater>
    </ItemTemplate>
</asp:Repeater>

Of course it doesn't work - the result is following - it's neither grouped nor a child is being displayed:
enter image description here

How can it be done - the control doesn't have to be repeater - it could be listview, bulleted list or something similar.

Best, if there's some "smart" way - so I just bind datatable to datasource, and the control makes the rest (grouping) for me. I would prefer to avoid splitting datasource table into two different sources or making SQL query for each parent item and playing with ItemDataBound event - as long as it's possible. If not - can you show me any way of doing that? .NET version: 4.0

Best regards,
Marcin

--Edit:
I've found following solution, however, I don't really like it because costly filtering source table for each item, I'm not sure how it will behave with large source datatable. I'll gladly hear if there's a better solution:

protected void repeaterParent_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    DataRowView drv = (DataRowView)e.Item.DataItem;
    string parent = drv["parent"].ToString();

    dt.DefaultView.RowFilter = string.Format("[parent]='{0}'", parent);
    DataTable dtChild =  dt.DefaultView.ToTable(true, "child");

    Repeater repeaterChild = (Repeater)e.Item.FindControl("repeaterChild");
    repeaterChild.DataSource = dtChild;
    repeaterChild.DataBind();

}
1
I would simply make a list of objects with child objects from the DataTable manually and then bind that into nested repeaters. Will have an overhead, but less than filtering every element. - Sami Kuhmonen

1 Answers

0
votes

You are on the right track, but ou have only one datasource and that is the input for the first repeater.

You need to add a second datasource to the second (nested) repeater. For example a function that returns the childs of the actual parent in the first datasource.

Nested Repeaters in ASP.NET