Monday, May 18, 2015

C# nested repeater for a menu with child items

For a two layered menu (parent menu items that can have child items) in C# the following solution can be used.
protected void rptMenuParent_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
    var row = (TopMenu)e.Item.DataItem;

    Repeater nestedRepeater = e.Item.FindControl("rptMenuChild") as Repeater;
    nestedRepeater.DataSource = row.Children;
    nestedRepeater.DataBind();
}

protected void Page_Load(object sender, EventArgs e)
{
    var menuItems = new List<TopMenuItem>();
    
    // add menu items
    
    rptMenuParent.DataSource = menuItems;
    rptMenuParent.DataBind();
}
public class TopMenu
{
    public MenuItem Parent { get; set; }

    public List<MenuItem> Children { get; set; }
}

public class MenuItem
{
    public string Link { get; set; }

    public string Text { get; set; }
}
<ul id="menu-header" class="menu">
    <asp:Repeater ID="rptMenuParent" runat="server" OnItemDataBound="rptMenuParent_OnItemDataBound">
        <itemtemplate>
            <li class="menu-item">
                <a href="<%# Eval("Parent.Link") %>"><%# Eval("Parent.Text") %></a>
                <asp:Repeater ID="rptMenuChild" runat="server">
                    <HeaderTemplate><ul class="sub-menu"></HeaderTemplate> 
                    <itemtemplate>
                        <li class="menu-item">
                            <a href="<%# Eval("Link") %>"><%# Eval("Text") %></a>
                        </li>
                    </itemtemplate>
                    <FooterTemplate></ul></FooterTemplate>
                </asp:Repeater>
            </li>
        </itemtemplate>
    </asp:Repeater>
</ul>
A list of TopMenu can be assigned to the parent repeater. This will output the first level (parent items) and the on data bound event will then pass the children (if any) to the child repeater. This could be extended to a third level by adding another list of menu items to the child and adding a third repeater.

No comments:

Post a Comment