2011-09-29 10 views
11

Sono estremamente estraneo a .NET e VB.NET e non riesco a capire come farlo. Dire che ho il codice come questo:Come posso convertire l'output di asp: SiteMapPath in un elenco?

<div class="breadcrumb"> 
    <asp:SiteMapPath ID="SiteMapPath1" runat="server"></asp:SiteMapPath> 
</div> 

Produce una serie di <span> s con > come separatori, qualcosa di simile:

<div class="breadcrumb"> 
    <span id="ctl00_SiteMapPath1"> 
    <a href="#ctl00_SiteMapPath1_SkipLink"> 
     <img alt="Skip Navigation Links" height="0" width="0" src="/Bonfield/WebResource.axd?d=PEpmmIw6qvhaEC3hEwXGjgvJKlzc3DOMu_e-zW-n6pfl6YR-iYjwmlvrYPb689EslKxysA7aoh_x_ALjLs5QXiz7NG41&amp;t=634245478914809245" style="border-width:0px;" /> 
    </a> 
    <span> 
     <a href="/Bonfield/Default.aspx">Home</a> 
    </span> 
    <span> &#187; </span> 
    <span>Showcase</span><a id="ctl00_SiteMapPath1_SkipLink"></a></span> 
</div> 

Come posso trasformarla in una lista come:

<ul> 
    <li>Home</li> 
    <li>Showcase</li> 
</ul> 

risposta

2

A questo punto è possibile averlo risolto ma è possibile utilizzare questa funzione per scorrere tutti gli elementi nel rootnode di una sitemap e dei relativi discendenti e creare un elenco annidato.

È possibile rimuovere If item.HasChildNodes Then sb.Append(ListChildNodes(item)) se si è interessati solo nel livello più alto

Public Function SiteMap() As String 
     Return ListChildNodes(System.Web.SiteMap.RootNode) 
    End Function 

    Private Function ListChildNodes(ByVal node As System.Web.SiteMapNode) As String 
     Dim sb As New System.Text.StringBuilder 

     sb.Append("<ul>") 
     For Each item As SiteMapNode In node.ChildNodes 
      sb.Append(String.Concat("<li><a href=""", item.Url, """>", item.Title, "</a></li>")) 
      If item.HasChildNodes Then sb.Append(ListChildNodes(item)) 
     Next 
     sb.Append("</ul>") 

     Return sb.ToString 
    End Function 

Per chi desidera la versione C#:

public string SiteMap() 
     { 
      return ListChildNodes(System.Web.SiteMap.RootNode); 
     } 
     private string ListChildNodes(System.Web.SiteMapNode node) 
     { 
      System.Text.StringBuilder sb = new System.Text.StringBuilder(); 

      sb.Append("<ul>"); 
      foreach (SiteMapNode item in node.ChildNodes) 
      { 
       sb.Append(string.Concat("<li><a href=\"", item.Url, "\">", item.Title, "</a></li>")); 
       if (item.HasChildNodes) 
        sb.Append(ListChildNodes(item)); 
      } 
      sb.Append("</ul>"); 

      return sb.ToString(); 
     } 

Poi nel codice si può chiamare per l'output la stringa alla pagina.

<h1>Site Map</h1> 
    <%=SiteMap()%> 
</div> 
+0

Questo è grande, tranne, tutto nel nodo si presenta:/ – SearchForKnowledge

0

Il più vicino a cui riesco a pensare è di inserire la sitemap in un controllo <asp:menu>. Questa uscita sarà tuttavia come una tabella HTML, ma visivamente verrà visualizzato un elenco:

<asp:Menu ID="leftNavigation" runat="server" DataSourceID="SiteMapDataSource1" 
     StaticDisplayLevels="1" MaximumDynamicDisplayLevels="1"> 
</asp:Menu> 
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" ShowStartingNode="false" /> 

Giocare con tutte le opzioni di stile e formattazione per ottenere l'output desiderato. See here per una dettagliata procedura dettagliata.

Oh, e, naturalmente, è anche possibile utilizzare una vista ad albero con una mappa del sito (vedere la stessa pagina).

2

Mentre non è possibile eliminare i tag span, è possibile ottenere ciò che si desidera. Mi sono imbattuto in questo stesso problema perché stavo usando un modello di sito CSS/HTML acquistato che il cliente voleva, ma l'intera faccenda era basata su <ul> e <li>. Refactoring del CSS sarebbe stato troppo doloroso, quindi ho trovato questa soluzione che funzionava bene senza alcuna modifica al codice CSS.

farete due cose:

  1. sovrascrivere il template del nodo predefinito con uno che utilizza <li> tag
  2. Avvolgere il tutto in un <ul> tag

Ecco un esempio:

<ul style="list-style-type: none;"> 
    <asp:SiteMapPath ID="SiteMapPath1" runat="server" > 
    <NodeTemplate> 
     <li> 
     <a href='<%# Eval("url") %>' title='<%# Eval("description") %>'><%# Eval("title") %></a> 
     </li> 
    </NodeTemplate> 
    </asp:SiteMapPath> 
</ul> 
+0

non ho alcun mezzo di prova più questo, ma se funziona lo avrebbe fatto stato perfetto per i miei bisogni. –

+3

Non funzionante, renderà il file all'interno di uno span –

+0

Mentre un po 'coinvolto, è possibile sbarazzarsi delle span. Dai un'occhiata alla mia risposta a questa domanda, se ti va. – Marcel

-1

L'opzione migliore per questo è convertire il SiteMapPath per utilizzare i modelli.

Nel <NodeTemplate> è possibile inserire gli elementi <li> con il formato necessario. Nel <PathSeparatorTemplate> è possibile posizionare il separatore.

Wrapp il controllo SiteMapPath con i tag <ul> e dovrebbe farlo.

Esempio:

<ul class="breadcrumb"> 
    <asp:SiteMapPath ID="SiteMapPath1" PathSeparator="" runat="server"> 
    <NodeTemplate> 
    <li> 
    <a href='<%# Eval("url") %>' title='<%# Eval("description") %>'><%# Eval("title") %></a> 
    </li> 
    </NodeTemplate> 
    <PathSeparatorTemplate> 
    <span class="divider">/</span> 
    </PathSeparatorTemplate> 
    </asp:SiteMapPath> 
</ul> 

Questa è un'opzione eccellente quando si utilizzano Bootstrap e ASP.NET

+0

Non metterebbe un 'intervallo tra ogni elemento dell'elenco? Gli elementi 'ul' possono contenere solo elementi' li'. –

+0

Sì, in realtà inserisce ancora gli span, sebbene ora contengano i li. -1 perché questo non risolve davvero la domanda dell'OP. – Marcel

0

Mentre un po 'coinvolto, questa è una soluzione che elimina in realtà le campate e rende una lista pulita.

Innanzitutto, eliminare gli span in eccesso modificando SiteMapPath. Ho derivato una classe NakedSiteMapPath che esegue questa operazione. Permette comunque l'utilizzo di spans espliciti nei template, se necessario:

/// <summary> 
///  A SiteMapPath, that does not render span elements. 
/// </summary> 
/// <remarks> 
///  To still allow explizit spans inside the node templates, immediately prefix the opening and closing span elements 
///  with the literal 
///  prefix "<!--KEEP NEXT SPAN-->" (without the double quotes) 
///  Example: 
///  <code> 
///  <PathSeparatorTemplate><!--KEEP NEXT SPAN--><span class="icon icon--greater"><!--KEEP NEXT SPAN--></span> 
///   </PathSeparatorTemplate> 
/// </code> 
///  Those spans (opening and closing) will be kept, but the prefix removed in the rendered output. 
/// </remarks> 
/// <devdoc> 
///  The MSDN doc has a nice example about a customized breadcrumb with a dropdown menu here: 
///  https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.sitemappath%28v=vs.110%29.aspx 
/// </devdoc> 
[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)] 
[ToolboxData("<{0}:NakedSiteMapPath runat=server></{0}:NakedSiteMapPath>")] 
public class NakedSiteMapPath : SiteMapPath { 
    /// <summary> 
    ///  Outputs server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter" /> object and stores 
    ///  tracing information about the control if tracing is enabled. 
    /// </summary> 
    /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter" /> object that receives the control content.</param> 
    public override void RenderControl(HtmlTextWriter writer) { 
     //Render to a local string, then remove all unnecessary spans 
     StringBuilder myStringBuilder = new StringBuilder(); 
     TextWriter myTextWriter = new StringWriter(myStringBuilder); 
     HtmlTextWriter myWriter = new HtmlTextWriter(myTextWriter); 
     base.RenderControl(myWriter); 

     string html = myStringBuilder.ToString(); 

     //Remove all spans, except those opening and closing spans wich have been marked with the literal comment "<!--KEEP NEXT SPAN-->" 
     const string matchOpenExceptSkipPrefix = @"(?<!\<\!--KEEP NEXT SPAN--\>)<span>"; 
     const string matchCloseExceptSkipPrefix = @"(?<!\<\!--KEEP NEXT SPAN--\>)</span>"; 
     html = Regex.Replace(html, matchOpenExceptSkipPrefix, String.Empty); 
     html = Regex.Replace(html, matchCloseExceptSkipPrefix, String.Empty); 
     html = html.Replace(@"<!--KEEP NEXT SPAN-->", String.Empty); 

     //finally, write the naked html out. 
     writer.Write(html); 
    } 
} 

Con ciò, gli span sono spariti. Per avere collegamenti personalizzati, come gli elementi li, è necessario utilizzare i modelli, come altri già hanno proposto. Ecco un esempio parte pagina ASPX con il NakedSiteMapPath:

<ol class="breadcrumb" role="navigation" aria-labelledby="pagebreadcrumbs"> 
    <my:NakedSiteMapPath runat="server" 
     PathDirection="RootToCurrent" 
     RenderCurrentNodeAsLink="False"> 
     <PathSeparatorTemplate><!--KEEP NEXT SPAN--><span class="icon icon--greater"><!--KEEP NEXT SPAN--></span></PathSeparatorTemplate> 
     <CurrentNodeTemplate> 
      <li class="active" aria-selected="true"> 
       <asp:Literal 
        Text='<%# Eval("Title") %>' 
        runat="server" /> 
      </li> 
     </CurrentNodeTemplate> 
     <NodeTemplate> 
      <li> 
       <asp:HyperLink 
        ID="lnkPage" 
        Text='<%# Eval("Title") %>' 
        NavigateUrl='<%# Eval("Url") %>' 
        ToolTip='<%# Eval("Description") %>' 
        runat="server" /> 
      </li> 
     </NodeTemplate> 
    </my:NakedSiteMapPath> 
</ol> 
+0

Domanda da un noob di ASP: come registrare il mio: NakedSiteMapPath in modo che tu possa usarlo in un file .aspx? – Fabien

Problemi correlati