I'm trying to implement a menu for my MVC3 solution. In this menu, I have 2 kind of links:
- classic links based on action + controller
Example 1: action = "Studies" + controller = "Main"
Example 2: action = "Contact" + controller = "Main"
- a little more complex links based on action + controller + routeValues
Example 3: action = "List" + controller = "Project" + routeValues = new { category = "BANK" }
Example 4: action = "List" + controller = "Project" + routeValues = new { category = "PHARMA" }
The menu is displayed like this:
- Studies
- Contact
- Bank
- Pharma
- ...
I would like to select the currently active menu item based on the active page. To achieve this, I implement an htmlHelper like this:
public static MvcHtmlString ActionMenuItem(this HtmlHelper htmlHelper, string lin开发者_运维百科kText, string actionName, string controllerName, object routeValues, object htmlAttributes)
{
var route = htmlHelper.ViewContext.RequestContext.RouteData;
var controller = route.GetRequiredString("controller");
var action = route.GetRequiredString("action");
// some code here...
if ((controller == controllerName) && (action == actionName))
{
tag.AddCssClass("active");
}
else
{
tag.AddCssClass("inactive");
}
// some code here...
}
The problem with this basic implementation is that the condition to activate/inactivate menu item is based only on the action and controller values. I also need to check my routeValues for the "complex links" (example 3 & 4).
How can I implement this?
Thanks for your help.
public static MvcHtmlString ActionMenuItem(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes)
{
var route = htmlHelper.ViewContext.RequestContext.RouteData;
var rvd = HtmlHelper.AnonymousObjectToHtmlAttributes(routeValues);
// some code here...
if (IsRouteValuesMatch(rvd, route))
{
tag.AddCssClass("active");
}
else
{
tag.AddCssClass("inactive");
}
// some code here...
}
private static bool IsRouteValuesMatch(RouteValueDictionary rvd, RouteData routeData)
{
foreach (var item in rvd)
{
var value1 = item.Value as string;
var value2 = routeData.Values[item.Key] as string;
if (!string.Equals(value1, value2, StringComparison.OrdinalIgnoreCase))
{
return false;
}
}
return true;
}
精彩评论