2010-01-21 16 views
5

Sto cercando di ottenere una buona idea su come modificare determinate parti della pagina in base a quale pagina sto guardando. Posso impostare determinati elementi con il controller della pagina, ma sto pensando di più sugli stati attivi del menu di navigazione globale (attualmente sottoposto a rendering con RenderAction nella pagina principale dell'applicazione).Come posso sapere quale pagina sono su un'applicazione ASP.NET MVC

Come se ho alcuni collegamenti di navigazione nella parte superiore dello schermo (usando così come esempio)

Domande | Tag | Utenti | ...

Se mi trovo nell'area "Domande" o pagina, desidero che il collegamento Domande sia attivo con un colore diverso.

Non voglio doverlo gestire su ogni pagina e inoltre non desidero inviare valori alla mia pagina principale e quindi inviarlo tramite RenderAction come penso che sarebbe disordinato. Quello che voglio è l'Azione per sapere solo in quale area è inserita la pagina renderizzata ed evidenziare gli elementi necessari.

+0

Non ci sono arrivato oggi ...speriamo domani. – rball

risposta

6

ViewMasterPage ha una proprietà ViewContext. ViewContext contiene i RouteData. Il RouteData dovrebbe avere una voce per il nome del controller e l'azione corrente, se non sono predefiniti. Potresti usarli nella tua logica sulla pagina principale per determinare quali elementi di navigazione evidenziare.

Analogamente, se si utilizza una vista parziale per la navigazione, si avrà accesso a RouteData tramite la proprietà ViewContext su ViewUserControl.

EDIT: Non penso che debba essere complicato.

<% 
    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 effetti, potrei addirittura rifattorizzarlo su un'estensione HTML per renderlo più semplice. Risulta che l'helper ha già un riferimento al ViewContext, quindi non è nemmeno necessario determinare il controller corrente nella vista. Si noti che sto mostrando solo una firma, è possibile aggiungere altre firme per gestire ulteriori dati di rotta e attributi html (questi dovrebbero essere uniti) se necessario.

<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

Molto bello, non lo sapevo. Lasciami fare un tentativo e vedere se funzionerà per me. – rball

+0

è molto più complicato di quanto dovrebbe essere. – Will

+0

Cambia ViewContext.RouteData ["controller"] a ViewContext.RouteData.Values ​​["controller"] e ha funzionato per me :) Grazie per l'aiuto. – rball

0

Questo è qualcosa che deve essere controllato dalla vista stessa. Se non si desidera modificare ogni vista, è possibile creare un controllo di visualizzazione utente (file .ascx) e aggiungerlo alla pagina principale.

+0

Ok, e poi nel controllo della vista utente, come potrei dire a quale pagina sono? Questa è la mia domanda. – rball

3

Buona domanda!

In passato ho risolto questo problema controllando i valori RouteData dal controller e dall'azione. Ma ora sto usando MvcContrib MenuBuilder per fare questo tipo di lavoro. guarda il loro codice di esempio per vedere come lavorare con questo.

+0

Ok buon suggerimento, darò un'occhiata. – rball

+0

Hai un link al loro codice di esempio? Ho cercato senza google – rball

+2

http://mvccontrib.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=37422, troverai l'esempio nel pacchetto del codice sorgente, soluzione MvcContrib.Samples.UI, nella cartella Samples. –

1

Dato il seguente in 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> 

All'interno del Users.aspx vista:

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

Quindi non c'è bisogno di fare qualsiasi tipo di strano analisi percorso o hurring questo o durring quello. Basta aggiungere un ContentPlaceHolder nell'intestazione della pagina principale, quindi in ogni vista fornire una definizione CSS aggiuntiva all'interno di questo segnaposto di contenuto che fa apparire la pagina come dovrebbe per quella particolare vista.

+2

Wow. Parla di fragile - devi farlo su ogni singola pagina o è rotto. Preferirei piuttosto scrivere un piccolo codice che tengo con il sistema di navigazione che avere tutto questo roba di stile incorporato sparsi in tutte le mie visualizzazioni. Cosa succede se decidi di cambiare il modo in cui viene eseguita l'evidenziazione? Quindi devi andare e cambiarlo ovunque. Che schifo. – tvanfosson

+1

fragile? Lol. Almeno puoi cambiare la tua vista senza * dover ricompilare *. Inoltre, questo consente ai ** designer ** di controllare il modo in cui appaiono le tue visualizzazioni (che è il loro lavoro, btw) al posto dei programmatori. – Will

+0

È possibile consentire al progettista di controllare l'aspetto della pagina facendo in modo che progettino le classi CSS applicate. Quindi puoi ancora cambiare la l & f al volo cambiando il foglio di stile anziché visitare ogni pagina di visualizzazione e cambiare il codice. – tvanfosson

Problemi correlati