如何判断我在ASP.NET MVC应用程序中的页面

时间:2022-03-22 04:16:56

I'm trying to get a good idea on how to modify certain parts of the page based on what page I'm looking at. I can set certain elements with the page's controller but I'm thinking more about the global navigation menu's (currently being rendered with a RenderAction in the application's MasterPage) active states.

我试图根据我正在查看的页面来了解如何修改页面的某些部分。我可以使用页面的控制器设置某些元素,但我正在考虑更多关于全局导航菜单(当前正在应用程序的MasterPage中使用RenderAction呈现)活动状态。

Like if I have some navigation links at the top of the screen (using SO's as an example)

就像我在屏幕顶部有一些导航链接一样(以SO为例)

Questions | Tags | Users | ...

问题|标签|用户| ...

If I'm in the "Questions" area or page then I want the Questions link to be active with a different color.

如果我在“问题”区域或页面中,那么我希望“问题”链接以不同的颜色激活。

I don't want to have to manage this on every page and plus I don't want to be sending in values to my master page and then sending it through the RenderAction as I think that'd be messy. What I want is the Action to just know what area the rendered page is in and highlight the necessary elements.

我不想在每个页面上管理这个并且我不想将值发送到我的母版页然后通过RenderAction发送它,因为我觉得它很混乱。我想要的是Action,只知道渲染页面所在的区域并突出显示必要的元素。

4 个解决方案

#1


6  

The ViewMasterPage has a ViewContext property. The ViewContext contains the RouteData. The RouteData should have an entry for the name of the controller and current action, if they aren't the default. You could use these in your logic on the master page to determine which navigation elements to highlight.

ViewMasterPage具有ViewContext属性。 ViewContext包含RouteData。 RouteData应该有一个控制器名称和当前操作的条目(如果它们不是默认值)。您可以在母版页的逻辑中使用这些来确定要突出显示的导航元素。

Similarly, if you used a partial view for the navigation, you would have access to the RouteData through the ViewContext property on the ViewUserControl.

同样,如果您使用局部视图进行导航,则可以通过ViewUserControl上的ViewContext属性访问RouteData。

EDIT: I don't think it needs to be complicated.

编辑:我不认为它需要复杂。

<%
   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>

In fact, I might even refactor it to an HTML extension to make it easier. Turns out that the helper already has a reference to the ViewContext so you don't even need to determine the current controller in the view. Note that I'm only showing one signature, you can add other signatures to handle additional route data and html attributes (these would need to be merged) as needed.

实际上,我甚至可以将它重构为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 );  
    }
}

#2


3  

Good question!

In the past I used to solve this with checking the RouteData values from the controller and action. But now i'm using the MvcContrib MenuBuilder to do this kind of job. look on their sample code to see how to work with this.

在过去,我曾经通过检查来自控制器和动作的RouteData值来解决这个问题。但现在我正在使用MvcContrib MenuBuilder来完成这项工作。查看他们的示例代码,看看如何使用它。

#3


1  

Given the following in Page.Master:

在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>

Within the view Users.aspx:

在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>

So you don't have to do any kind of weird route parsing or hurring this or durring that. You just add a ContentPlaceHolder in your master page's header, then in each view provide some additional CSS definition within this content placeholder that makes the page look how it should for that particular view.

因此,您不必进行任何类型的奇怪路由解析或推迟或推迟。您只需在母版页的标题中添加ContentPlaceHolder,然后在每个视图中在此内容占位符中提供一些额外的CSS定义,使页面看起来应该如何针对该特定视图。

#4


0  

This is something that should be controlled from the view itself. If you don't want to modify every view, you can create an user view control (.ascx files) and add it to the master page.

这是应该从视图本身控制的东西。如果您不想修改每个视图,可以创建用户视图控件(.ascx文件)并将其添加到母版页。

#1


6  

The ViewMasterPage has a ViewContext property. The ViewContext contains the RouteData. The RouteData should have an entry for the name of the controller and current action, if they aren't the default. You could use these in your logic on the master page to determine which navigation elements to highlight.

ViewMasterPage具有ViewContext属性。 ViewContext包含RouteData。 RouteData应该有一个控制器名称和当前操作的条目(如果它们不是默认值)。您可以在母版页的逻辑中使用这些来确定要突出显示的导航元素。

Similarly, if you used a partial view for the navigation, you would have access to the RouteData through the ViewContext property on the ViewUserControl.

同样,如果您使用局部视图进行导航,则可以通过ViewUserControl上的ViewContext属性访问RouteData。

EDIT: I don't think it needs to be complicated.

编辑:我不认为它需要复杂。

<%
   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>

In fact, I might even refactor it to an HTML extension to make it easier. Turns out that the helper already has a reference to the ViewContext so you don't even need to determine the current controller in the view. Note that I'm only showing one signature, you can add other signatures to handle additional route data and html attributes (these would need to be merged) as needed.

实际上,我甚至可以将它重构为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 );  
    }
}

#2


3  

Good question!

In the past I used to solve this with checking the RouteData values from the controller and action. But now i'm using the MvcContrib MenuBuilder to do this kind of job. look on their sample code to see how to work with this.

在过去,我曾经通过检查来自控制器和动作的RouteData值来解决这个问题。但现在我正在使用MvcContrib MenuBuilder来完成这项工作。查看他们的示例代码,看看如何使用它。

#3


1  

Given the following in Page.Master:

在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>

Within the view Users.aspx:

在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>

So you don't have to do any kind of weird route parsing or hurring this or durring that. You just add a ContentPlaceHolder in your master page's header, then in each view provide some additional CSS definition within this content placeholder that makes the page look how it should for that particular view.

因此,您不必进行任何类型的奇怪路由解析或推迟或推迟。您只需在母版页的标题中添加ContentPlaceHolder,然后在每个视图中在此内容占位符中提供一些额外的CSS定义,使页面看起来应该如何针对该特定视图。

#4


0  

This is something that should be controlled from the view itself. If you don't want to modify every view, you can create an user view control (.ascx files) and add it to the master page.

这是应该从视图本身控制的东西。如果您不想修改每个视图,可以创建用户视图控件(.ascx文件)并将其添加到母版页。