Захотелось мне меню с закладками – как в стандартной заготовке MVC3 Web Application (Home - About), но чтоб активная вкладка выделять каким то образом – для простоты цветом. В обычном приложении Web Forms это можно сделать довольно несложно на серверной стороне. В приложении MVC3 для меня это оказалось непростой задачей. Поэтому буду ее решать.
Итак, у нас есть список, который и представляет собой меню:
<ul id="menu">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
</ul>
В CSS-файле есть раздел “TAB MENU”, в котором описывается стиль нашего меню, в том числе есть такое описание:
ul#menu li.selected a {
background-color: #fff;
color: #000;
}
Понятно, что описывается стиль активного элемента списка. Теперь надо динамически в зависимости от активной страницы устанавливать стиль selected соответствующему элементу списка. Создадим несложную модель нашего меню (листинг 1).
Листинг 1 – Модель меню
public class TabMenu
{
private TabMenu(string text, string action, string controller)
{
Text = text;
Action = action;
Controller = controller;
}
public static TabMenu Create(string text, string action, string controller)
{
return new TabMenu(text, action, controller);
}
public string Text { get; private set; }
public string Action { get; private set; }
public string Controller { get; private set; }
}
Как видно, закладка имеет свойства: текст, т.е. что будет написано не закладке, ссылка и контроллер.
Теперь создадим элемент управления HTML для представления (листинг 2).
Листинг 2 – Компонент для меню
public static class MenuHtmlHelper
{
public static HtmlString TabbedMenu(this HtmlHelper helper, IEnumerable<TabMenu> tabs)
{
RouteData route = helper.ViewContext.RequestContext.RouteData;
string controller = route.GetRequiredString("controller");
string action = route.GetRequiredString("action");
string menu = "<ul id=\"menu\">";
foreach (var tab in tabs)
{
if (controller == tab.Controller && action == tab.Action)
menu += "<li class='selected'>" + helper.ActionLink(tab.Text, tab.Action,
tab.Controller) + "</li>";
else
menu += "<li>" + helper.ActionLink(tab.Text,
tab.Action, tab.Controller) + "</li>";
}
menu += "</ul>";
return MvcHtmlString.Create(menu);
}
}
Как видно, компонент получает список закладок меню. У той закладки, у которой контроллер и ссылка совпадают с контроллером и ссылкой текущей страницы устанавливается стиль selected для элемента списка. Не забудьте подключить пространства:
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;
Теперь в файле _Layout.cshtml заменяем старое меню на новое (листинг 3).
Листинг 3 – Код меню в представлении
@Html.TabbedMenu(new List<TabMenu> {
TabMenu.Create("Главная", "Index", "Home"),
TabMenu.Create("О проекте", "About", "Home")
})
Чтоб представление «увидело» наш компонент надо подключить:
@using MvcApplication3.Models;
Практически, все. Результат на рисунке 1.
Успехов!
4 комментария:
Здравствуйте. Появился вопрос по меню.
Я хочу сделать что бы было разное меню в зависимости от того, к какой роли относится пользователь.
В стандартной реализации я могу это легко сделать используя конструкцию для отдельных пунктов меню:
if (HttpContext.Current.User.IsInRole("Manager")
{
}
Но используя ваш вариант меню это уже не сделать. Может у Вас есть решение?
Добрый день!
Я не сталкивался. Но ведь для начала нужно знать, какой используется механизм аутентификации на сайте.
Я использую стандартную asp.net
asp.net - это для разработки.
а мы говорим об аутентификации. как я вижу, Ваш сайт использует стандартную аутентификацию на основе Membership API (это происходит через кнопочку "Вход"). В нем есть и роли, но как ими пользоваться, я не знаю - не приходилось. Будет время, постараюсь разобраться.
Отправить комментарий