2008-11-13 4 views
13

Как создать вкладку навигации с вкладкой «Текущий», выделенной в пользовательском интерфейсе?Простой способ установить активную вкладку с помощью контроллеров и пользовательского контроля в ASP.NET MVC?

+0

Просьба сначала изложить это в форме вопроса, а затем предоставить ответ в виде отдельного сообщения. Когда я увижу, что вы исправили его, я удалю свой нижний план. В противном случае мне придется закрыть его как «не настоящий вопрос». – 2008-11-13 17:54:37

+1

Исправлено это для него. – FlySwat 2008-11-13 18:01:17

+0

Вопрос был такой большой и теперь такой маленький: P haha ​​ – 2008-11-13 18:01:30

ответ

10

Перед MVC я просмотрел путь к файлу и выяснил, какая вкладка была точной. Теперь это намного проще, вы можете назначить текущую вкладку на основе текущего контроллера.

Проверьте это ...

Большая часть работы происходит в UserControl.

public partial class AdminNavigation : ViewUserControl 
{ 
    /// <summary> 
    /// This hold a collection of controllers and their respective "tabs." Each Tab should have at least one controller in the collection. 
    /// </summary> 
    private readonly IDictionary<Type, string> dict = new Dictionary<Type, string>(); 

    public AdminNavigation() 
    { 
     dict.Add(typeof(BrandController), "catalog"); 
     dict.Add(typeof(CatalogController), "catalog"); 
     dict.Add(typeof(GroupController), "catalog"); 
     dict.Add(typeof(ItemController), "catalog"); 
     dict.Add(typeof(ConfigurationController), "configuration"); 
     dict.Add(typeof(CustomerController), "customer"); 
     dict.Add(typeof(DashboardController), "dashboard"); 
     dict.Add(typeof(OrderController), "order"); 
     dict.Add(typeof(WebsiteController), "website"); 
    } 

    protected string SetClass(string linkToCheck) 
    { 
     Type controller = ViewContext.Controller.GetType(); 
     // We need to determine if the linkToCheck is equal to the current controller using dict as a Map 
     string dictValue; 
     dict.TryGetValue(controller, out dictValue); 

     if (dictValue == linkToCheck) 
     { 
      return "current"; 
     } 
     return ""; 
    } 
} 

Затем в .ascx части usercontol вызова в метод SetClass, чтобы проверить связь против Dict. Например:

<li class="<%= SetClass("customer") %>"><%= Html.ActionLink<CustomerController>(c=>c.Index(),"Customers",new{@class="nav_customers"}) %></li> 

Все, что вам нужно, это CSS, чтобы выделить текущую вкладку. Есть куча разных способов сделать это, но вы можете начать с некоторыми идеями здесь: http://webdeveloper.econsultant.com/css-menus-navigation-tabs/ Ох, и не забудьте поставить UserControl на вашей странице (или Masterpage) ...

<% Html.RenderPartial("AdminNavigation"); %> 
3

Один из методов, которые я использую в текущем проекте - это также помогает для других потребностей CSS в CSS.

Во-первых, HTML помощник, который возвращает строку, которая представляет текущий контроллер и действие:

public static string BodyClass(RouteData data) { 
    return string.Format("{0}-{1}", data.Values["Controller"], data.Values["Action"]).ToLower(); 
} 

Затем добавить вызов этого помощника в вашей главной страницы:

<body class="<%=AppHelper.BodyClass(ViewContext.RouteData) %>"> 
... 
</body> 

Теперь, вы можете настроить таргетинг на определенные страницы с помощью своего CSS. Чтобы ответить на ваш точный вопрос о навигации:

#primaryNavigation a { ... } 
.home-index #primaryNavigation a#home { ... } 
.home-about #primaryNavigation a#about { ... } 
.home-contact #primaryNavigation a#contact { ... } 
/* etc. */ 
10

Я написал несколько простых вспомогательных классов для решения этой проблемы. В решении рассматривается как тот контроллер, который используется, так и какое действие в контроллере.

public static string ActiveTab(this HtmlHelper helper, string activeController, string[] activeActions, string cssClass) 
{ 
    string currentAction = helper.ViewContext.Controller. 
    ValueProvider.GetValue("action").RawValue.ToString(); 
    string currentController = helper.ViewContext.Controller. 
    ValueProvider.GetValue("controller").RawValue.ToString(); 
    string cssClassToUse = currentController == activeController && 
          activeActions.Contains(currentAction) 
          ? cssClass 
          : string.Empty; 
    return cssClassToUse; 
} 

Вы можете вызов этого метода расширения с:

Html.ActiveTab("Home", new string[] {"Index", "Home"}, "active") 

Это будет возвращать «активный», если мы на HomeController либо в «Index» или акции «Home». Я также добавил некоторые дополнительные перегрузки в ActiveTab, чтобы упростить их использование, вы можете прочитать всю запись в блоге: http://www.tomasjansson.com/blog/2010/05/asp-net-mvc-helper-for-active-tab-in-tab-menu/

Надеюсь, это поможет кому-то.

С уважением, --Tomas

0

MVC по умолчанию Site.css поставляется с классом по имени 'selectedLink', который должен быть использован для этого.

Добавьте следующую строку в ваш список ul в _Layout.cshtml:

@{ 
    var controller = @HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString(); 
} 
<ul id="menu">     
    <li>@Html.ActionLink("Home", "Index", "Home", null, new { @class = controller == "Home" ? "selectedLink" : "" })</li> 
    ... 
</ul> 

Я знаю, что это не чистый. Но просто быстрый и грязный способ заставить вещи прокатиться, не вмешиваясь в частичные взгляды или любые подобные.