1

I want to achieve n level data hierarchy in using repeater control in asp.net. Is there any solution to achieve that hierarchy ?

4
  • 1
    Short answer: Yes. Longer answer: yes, but we prefer to see what you've tried so far, and where you're having trouble getting it working Commented Mar 31, 2015 at 9:01
  • I have one repeater control that contain another repeater control and second contain user control that have another repeater control. I want to continue that hierarchy up to n level using that user control. Commented Mar 31, 2015 at 9:03
  • Are you wanting to implement a nested repeater with however many levels as are necessary to represent your data - basically a recursive template? Are you trying to render some kind of treeview? Commented Mar 31, 2015 at 9:05
  • yes. recursive template using repeater control and user control Commented Mar 31, 2015 at 9:06

2 Answers 2

2

For this answer I'm going to suggest creating your template programmatically - see here: https://msdn.microsoft.com/en-us/library/aa289501 . There is probably some way to use templates that have been created in markup, but this seems easier, and definitely more flexible.

I start out with a page with just a repeater (not template)

<body>
    <form id="form1" runat="server">
    <div>
        <asp:Repeater runat="server" ID="TestRepeater">
        </asp:Repeater>
    </div>
    </form>     
</body>

and a data class

public class DataClass
{
    public string Name { get; set; }
    public List<DataClass> Children { get; set; }
}

For the template we use the following class:

public class DataTemplate : ITemplate
{
    public void InstantiateIn(Control container)
    {
        var name = new Literal();
        var repeater = new Repeater();

        name.DataBinding += BindingLiteral;
        repeater.DataBinding += BindingRepeater;

        // this here makes it recursive
        repeater.ItemTemplate = new DataTemplate();

        container.Controls.Add(name);
        container.Controls.Add(repeater);
    }

    private void BindingLiteral(object sender, System.EventArgs e)
    {
        var name = (Literal)sender;
        var container = (RepeaterItem)name.NamingContainer;
        name.Text = String.Concat("<h2>", DataBinder.Eval(container.DataItem, "Name").ToString(), "</h2>");
    }

    private void BindingRepeater(object sender, System.EventArgs e)
    {
        var name = (Repeater)sender;
        var container = (RepeaterItem)name.NamingContainer;
        name.DataSource = DataBinder.Eval(container.DataItem, "Children");
    }
}

Obviously you'll want to use a more sophisticated template. Notice that if you currently have a template in markup, you could simply take the code that has been generated by the markup parser, and adapt it to your needs.

Now in the code behind of the page we simple assign the ItemTemplate and DataSource:

public partial class Test : System.Web.UI.Page
{
    protected void Page_Init(object sender, EventArgs e)
    {
        TestRepeater.DataSource = GetTestData();
        TestRepeater.ItemTemplate = new DataTemplate();
        TestRepeater.DataBind();
    }
}

Nice thing about this is your template is just a class, so you could add a public Int32 Depth { get; set; } to it, and change the generated controls based on your depth.

Sign up to request clarification or add additional context in comments.

Comments

1

Another solution, without creating the template programmatically :

Using a simple data class :

public class DataClass
{
    public string Name { get; set; }
    public List<DataClass> Children { get; set; }
}

In the ASPX markup create your parent repeater, put your item display code in the ItemTemplate, and add a second "empty" repeater :

<body>
    <form id="form1" runat="server">
    <div>
        <asp:Repeater runat="server" ID="ParentRepeater" OnItemDataBound="Repeater_ItemDataBound">
            <ItemTemplate>
                <asp:Literal runat="server" Text="<%# Eval("Name") %>"></asp:Literal>
                <asp:Repeater runat="server" ID="ChildRepeater" OnItemDataBound="Repeater_ItemDataBound" Visible="false">
                </asp:Repeater>
            </ItemTemplate>
        </asp:Repeater>
    </div>
    </form>     
</body>

And in the code-behind :

protected void Repeater_ItemDataBound(object sender, RepeaterItemEventArgs e) {
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
        DataClass currentItem = (DataClass)e.Item.DataItem;

        if (currentItem.Children.Count > 0) {
            Repeater ChildRepeater = (Repeater)e.Item.FindControl("ChildRepeater");

            ChildRepeater.DataSource = currentItem.Children;
            ChildRepeater.ItemTemplate = ParentRepeater.ItemTemplate;
            ChildRepeater.Visible = true;
            ChildRepeater.DataBind();
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.