2010-01-21 1 views
5

Я пытаюсь получить представление о том, как изменить некоторые части страницы на основе того, на какой странице я смотрю. Я могу установить некоторые элементы с помощью контроллера страницы, но я больше думаю о глобальном навигационном меню (которое в настоящее время отображается с активными состояниями RenderAction в приложении MasterPage).Как я могу определить, на какой странице я в ASP.NET MVC-приложении

Как, если у меня есть некоторые навигационные ссылки в верхней части экрана (с помощью SO это в качестве примера)

Вопросы | Теги | Пользователи | ...

Если я нахожусь в области «Вопросы» или страницы, тогда я хочу, чтобы ссылка «Вопросы» была активной с другим цветом.

Я не хочу, чтобы управлять этим на каждой странице, и я не хочу, чтобы отправлять значения на мою главную страницу, а затем отправлять ее через RenderAction, поскольку я думаю, что это было бы грязно. Я хочу, чтобы Action просто узнал, в какой области находится отображаемая страница, и выделите необходимые элементы.

+0

Не добрался до него сегодня ...надеюсь завтра. – rball

ответ

6

ViewMasterPage имеет свойство ViewContext. ViewContext содержит RouteData. У RouteData должна быть запись для имени контроллера и текущего действия, если они не являются стандартными. Вы можете использовать их в своей логике на главной странице, чтобы определить, какие элементы навигации нужно выделить.

Аналогичным образом, если вы использовали частичный вид для навигации, у вас будет доступ к RouteData с помощью свойства ViewContext в ViewUserControl.

EDIT: Я не думаю, что это должно быть сложно.

<% 
    var current = this.ViewContext.RouteData.Values["controller"] as string ?? "home"; 
%> 

<ul> 
    <li><%= Html.ActionLink("Home", "index", "home", null, new { @class = current == "home" ? "highlight" : "" } %></li> 
    ... 
</ul> 

Фактически, я бы даже реорганизовал его на расширение HTML, чтобы упростить его. Оказывается, что помощник уже имеет ссылку на ViewContext, поэтому вам даже не нужно определять текущий контроллер в представлении. Обратите внимание, что я показываю только одну подпись, вы можете добавить другие подписи для обработки дополнительных данных маршрута и html-атрибутов (они должны быть объединены) по мере необходимости.

<ul> 
    <li><%= Html.NavLink("Home", "index", "home") %></li> 
    ... 
</ul> 

public static class HtmlHelperExtensions 
{ 
    public static string NavLink(this HtmlHelper helper, 
            string text, 
            string action, 
            string controller) 
    { 
      string current = helper.ViewContext.RouteData.Values["controller"] as string; 
      object attributes = null; 
      if (string.Equals(current, controller, StringComparison.OrdinalIgnoreCase)) 
      { 
       attributes = new { @class = "highlight" }; 
      } 

      return this.ActionLink(text, action, controller, null, attributes); 
    } 
} 
+0

Очень круто, я этого не знал. Позвольте мне сказать, что пойдем и посмотрим, будет ли это работать для меня. – rball

+0

это намного сложнее, чем нужно. – Will

+0

Изменить ViewContext.RouteData ["controller"] на ViewContext.RouteData.Values ​​["controller"], и это сработало для меня :) Спасибо за помощь. – rball

0

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

+0

Итак, а затем в элементе управления пользовательского вида, как бы я потом рассказать, на какой странице я? Это мой вопрос. – rball

3

Хороший вопрос!

В прошлом я использовал это, проверяя значения RouteData от контроллера и действия. Но теперь я использую MvcContrib MenuBuilder для выполнения этой работы. посмотрите на свой пример кода, чтобы узнать, как с этим работать.

+0

Хорошо, хорошее предложение, я посмотрю. – rball

+0

Получил ссылку на свой пример кода? Я googled без sucess – rball

+2

http://mvccontrib.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=37422, вы найдете пример в пакете исходного кода, решение MvcContrib.Samples.UI, в папке Samples. – 2010-01-21 22:51:49

1

Учитывая следующее Page.Master:

<head runat="server"> 
    <link href="Standard.CSS" rel="stylesheet" type="text/css" /> 
    <asp:ContentPlaceHolder ID="header" runat="server" /> 
</head> 
<!-- and later on in the file --> 
<ul> 
    <li> 
    <a href="/questions" class="question">Questions</a> 
    </li> 
    <li> 
    <a href="/questions" class="user">Users</a> 
    </li> 
</ul> 

в поле зрения Users.aspx:

<asp:Content ID="header" ContentPlaceHolderID="header" runat="server"> 
    <title>User's Page</title> 
    <style type="text/css"> 
     .user 
     { 
      background-color:yellow; 
     } 
    </style> 
</asp:content> 

Таким образом, вы не должен делать какие-либо странный маршрут разбора или hurring этой или задерживает это. Вы просто добавляете ContentPlaceHolder в заголовок главной страницы, а затем в каждом представлении укажите некоторое дополнительное определение CSS в этом заполнителе содержимого, что делает страницу выглядящей так, как она должна выглядеть для этого конкретного вида.

+2

Ничего себе. Разговор о хрупкости - вы должны сделать это на каждой странице или сломать. Я бы предпочел написать небольшой код, который я использую в навигационной системе, чем все эти встроенные стили, разбросанные по всем моим взглядам. Что делать, если вы решите изменить способ выделения? Тогда вам нужно пойти и изменить его повсюду. Тьфу. – tvanfosson

+1

Хрупкий? Лол. По крайней мере, вы можете изменить свои взгляды без необходимости перекомпиляции *. Кроме того, это позволяет ** дизайнерам ** контролировать, как выглядят ваши взгляды (а это их работа, кстати), а не программисты. – Will

+0

Вы позволяете дизайнеру контролировать, как выглядит страница, создавая для них классы CSS, которые вы применяете. Затем вы все равно можете изменить l & f на лету, изменив таблицу стилей, а не посещая каждую страницу просмотра и меняя код. – tvanfosson