2011-04-14 75 views
0

對於我的學習,我正在用ASP.NET MVC3構建一個文檔管理解決方案。下面是網頁]:在我的asp.net mvc解決方案中集成一個通用菜單

  • 搜索/結果頁(產品清單)
  • 喜愛的網頁(產品清單)
  • 編輯頁面
  • 一個創建頁面

我也有一個Site.Master頁面,我在屏幕的左側顯示一個樹形菜單。因此,無論用戶在網站中的哪個位置,樹視圖菜單都會通過在菜單中強調其位置來顯示其位置。

爲建設樹狀菜單,我用下面的代碼(清洗方便閱讀):

 <ul id="treemenu1" class="treeview">          
       <li>Documents 
        <ul> 
         <%= Html.TreeviewMenu(TreeMenu.Create("Search", "Search", "Affaires", null))%> 
         <%= Html.TreeviewMenu(TreeMenu.Create("Favorite", "Favorite", "Affaires", null))%> 
         <%= Html.TreeviewMenu(TreeMenu.Create("New", "Create", "Affaires", null))%> 
        </ul> 
       </li> 
     </ul> 

的問題是,我需要強調在我的菜單中的活動項目。所以如果用戶顯示搜索頁面,我的搜索菜單條目必須加下劃線。我該如何繼續?我正在考慮將此信息集成到傳遞給每個視圖頁面的強類型視圖模型中,但因爲每個頁面都使用了不同的視圖模型,所以失敗了。我不喜歡使用會話變量,因爲它不是一個乾淨的解決方案。

任何想法?

帶會話變量的解決方案:我將「當前菜單項」保存在會話變量(來自我的控制器)中。因此,每當Site.Master頁面重新加載時,它都會重新創建每個樹視圖菜單項。對於每一個,它都檢查該項是否等於會話變量。如果是,則將「已選擇」類添加到該項目(css用藍色突出顯示)。

我不太喜歡使用會話變量。也許有更優雅的解決方案?

回答

1

如何使用輔助:

public static MvcHtmlString MenuItem(
    this HtmlHelper htmlHelper, 
    string text, 
    string action, 
    string controller 
) 
{ 
    var li = new TagBuilder("li"); 
    var routeData = htmlHelper.ViewContext.RouteData; 
    var currentAction = routeData.GetRequiredString("action"); 
    var currentController = routeData.GetRequiredString("controller"); 
    if (string.Equals(currentAction, action, StringComparison.OrdinalIgnoreCase) && 
     string.Equals(currentController, controller, StringComparison.OrdinalIgnoreCase)) 
    { 
     li.AddCssClass("active"); 
    } 
    li.InnerHtml = htmlHelper.ActionLink(text, action, controller).ToHtmlString(); 
    return MvcHtmlString.Create(li.ToString()); 
} 

然後:

<ul> 
    <%= Html.MenuItem("Search", "Search", "Affaires") %> 
    <%= Html.MenuItem("Favorite", "Favorite", "Affaires") %> 
    <%= Html.MenuItem("New", "Create", "Affaires") %> 
</ul> 

如果你導航到/Affaires/Favorite可能產生以下

<ul> 
    <li><a href="/Affaires/Search">Search</a></li> 
    <li class="active"><a href="/Affaires/Favorite">Favorite</a></li> 
    <li><a href="/Affaires/Create">New</a></li> 
</ul> 
+0

是的,可能是最合乎邏輯的事情。不能相信我沒有想到這一點。 – 2011-04-14 16:34:48

+0

@Darin:您的解決方案是最有效的邏輯。那就是我剛開始使用的解決方案。直到我在我的頁面中使用表單來管理我的搜索頁面生成的表格中的選中項目。如果表單在我的控制器中提交併威脅(將我的表單發佈到名爲ManageCheckedItems的操作),接下來我們返回到相同的視圖頁面。然後重新加載Site.Master頁面,並執行html助手(與你的一樣)。這裏**的問題是這裏的routeData.GetRequiredString(「action」)等於ManageCheckedItems而不是Search! – Bronzato 2011-04-14 17:09:38

+0

這是我解決這個問題的最大問題。因此總結一下:如果我使用的表單的後置操作與初始操作頁面不同,則在返回重新加載我的頁面時出現問題。我不知道我是否清楚。 – Bronzato 2011-04-14 17:10:08

0

那麼,有一個簡單而有效的解決方案:讓每個頁面指示是否爲活動頁面,並用jQuery設置一個css類。

假設你的渲染HTML如下:

<ul id="treemenu1" class="treeview">          
    <li>Documents 
     <ul> 
      <li class="search"></li> 
      <li class="favorite"></li> 
     </ul> 
    </li> 
</ul> 

在每個頁面的底部,這樣做(這將坐在搜索視圖):

<script type="text/javascript"> 
    $(document).ready(function() { 
     // Set active nav 
     $('#treemenu1 li.search').addClass('selected'); 
    }); 
</script> 

UPDATE基於新信息

小清潔劑th會話可能會使用控制器的ViewBag屬性。

public ActionResult Search(/*whatever*/) 
{ 
    // do things 

    // set the selevted view 
    ViewBag.SelectedMenuItem = "search"; 

    return View(); 
} 

然後在你的母版頁,你可以對證<%: ViewBag.SelectedMenuItem %>

注意SelectedMenuItem是一個隨機名稱。 The ViewBag property is of type dynamic所以你可以使用你喜歡的任何屬性名稱。

+0

它可能是一個解決方案,但我有相同的查看頁面用於多種目的(搜索,最喜歡的...),所以在這種情況下,我有一個問題。否則你的解決方案就可以工我會考慮一下。也許還有其他的選擇?不管怎麼說,還是要謝謝你。 – Bronzato 2011-04-14 12:23:15

+0

@Bronzato - 你是什麼意思,「多個目的相同的查看頁面」? – 2011-04-14 12:46:12

+0

我的意思是說,我有一個名爲Search.aspx的頁面用於搜索和收藏夾菜單選項。我在我的問題中添加了更多信息(請參閱上文)。 – Bronzato 2011-04-14 16:17:20