How can I turn the output of asp:SiteMapPath into a list?

前端 未结 5 2363
借酒劲吻你
借酒劲吻你 2021-02-20 04:52

I\'m extremely unfamiliar with both .NET and VB.NET and can\'t quite figure out how to do this. Say I have code like this:

&
相关标签:
5条回答
  • 2021-02-20 05:10

    You may have solved this by now but you could use this function to loop through all the items in the rootnode of a sitemap and their descendants and build up a nested list.

    You can remove If item.HasChildNodes Then sb.Append(ListChildNodes(item)) if you are only interested in the top level

     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
    

    For those who would like the C# version:

    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();
            }
    

    Then in your code you can just call to output the string to the page.

    <h1>Site Map</h1>
        <%=SiteMap()%>
    </div>
    
    0 讨论(0)
  • 2021-02-20 05:14

    The closest I can think of is putting you sitemap into a <asp:menu> control. This will however output as an html table, but visually it will show up a list:

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

    Play around with all the styling and formatting options to get your desired output. See here for a detailed walkthrough.

    Oh, and of course you could also look into using a treeview with a sitemap instead (see the same page).

    0 讨论(0)
  • 2021-02-20 05:14

    The best option for this is to convert the SiteMapPath to use Templates.

    In the <NodeTemplate> you can place <li> elements with the format you need. In the <PathSeparatorTemplate> you can place the separator.

    Wrapp the SiteMapPath control with the <ul> tags and that should do it.

    Example:

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

    This is excelent option when using Bootstrap and ASP.NET

    0 讨论(0)
  • 2021-02-20 05:24

    While you can't get rid of the span tags, you CAN accomplish what you want. I ran into this same issue because I was using a purchased CSS/HTML site template the client wanted, but the entire thing was based on <ul>'s and <li>'s. Refactoring the CSS would have been too painful, so I found this solution that worked well without any changes to the CSS code.

    You'll do two things:

    1. Override the default Node template with one that uses <li> tags
    2. Wrap the whole thing in a <ul> tag

    Here's an example:

    <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 讨论(0)
  • 2021-02-20 05:35

    While a little involved, this is a solution that actually removes the spans and renders a clean list.

    First, get rid of those excess spans by modifying the SiteMapPath. I have derived a class NakedSiteMapPath that does this. It still allows the usage of explicit spans in templates, if needed:

    /// <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);
        }
    }
    

    With that, the spans are gone. To have custom links, like the li elements, you will need to use the templates, as others already have proposed. Here's an example ASPX page part with the 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 讨论(0)
提交回复
热议问题