Создание меню с древовидной структурой

В статье приведен пример создания меню с древовидной структурой. В данном примере создано простое дерево с родительским пунктом и с дочерними пунктами меню. Реализовать данное дерево можно для любого простого пункта меню (без дополнительной разметки, например, без фильтров под пунктом меню). В примере каждый элемент дерева является фильтром.

Пример отображения данных

Рис. 1. Меню древовидной структуры

Методы расширения (интерфейса)

Точка расширения (интерфейс) IMenuItemRenderer имеет следующие методы:

/// <summary>
/// Имеет ли элемент меню кастомное отображение
/// </summary>
/// <param name="item">Элемент меню для построения дерева</param>
/// <returns></returns>
bool HasCustomRender(MenuItemNode item);

/// <summary>
/// Сгенерировать разметку для элемента меню
/// </summary>
/// <param name="htmlHelper">Хелпер</param>
/// <param name="item">Элемент меню для построения дерева</param>
/// <returns></returns>
MvcHtmlString Render(HtmlHelper htmlHelper, MenuItemNode item);

Пример класса точки расширения

[Component]
public class MenuItemRenderer : IMenuItemRenderer
{
    public bool HasCustomRender(MenuItemNode item)
    {
        return item.Code == MyObjectMenu.NewPoint;
    }

    public MvcHtmlString Render(HtmlHelper htmlHelper, MenuItemNode item)
    {
        const bool highlightPath = true;
        var html = htmlHelper;
        var list = new List<TreeMenuNode>();

        if (item.Code == MyObjectMenu.NewPoint)
        {
            list.Add(new TreeMenuNode
            {
                id = "my_menu",
                Selected = true,
                text = SR.T("Все объекты"),
                href = html.Url().Action("FilterObject", "Home", new { area = RouteProvider.AreaName }),
                children = new List<TreeMenuNode>
                {
                    new TreeMenuNode
                    {
                        id = "Emails",
                        text = SR.T("Письма"),
                        href = html.Url().Action("FilterObject", "Home", new {area = RouteProvider.AreaName, obj = SR.T("Письмо")})
                    },
                    new TreeMenuNode
                    {
                        id = "ICQ",
                        text = SR.T("ICQ"),
                        href = html.Url().Action("FilterObject", "Home", new {area = RouteProvider.AreaName, obj = SR.T("ICQ")})
                    },
                }
            });
        }

        return html.Tree(list, "main_menu_tree_channels", highlightPath);
    }
}
Примечание:
Каждый пункт меню вызывает действие FilterObject в контроллере Home и передает в него параметр для фильтрации.

Пример используемого кода контроллера Home:

[ContentItem]
public ActionResult FilterObject(string obj)
{
      var filter = CreateFilter();
        filter.Type = new DropDownItem(obj);
        return View("FilterObjects", CreateGridData(new GridCommand(), filter));
}

Ссылки на элементы API

IMenuItemRenderer
IMenuItemsProvider