10

SharePointソリューションのカスタムの現在の(左)ナビゲーションに取り組んでいます。

私が必要としているのは、ナビゲーションのルートがバリエーションWebであり、ルートWebの直接の子であるということです。このバリエーションの直接の子であるすべてのサイトとページは、展開されていなくても表示されるはずです。現在のサイトの祖先であるサイトのみを展開する必要があります...現在のサイト/ページまでずっと拡張する必要があります。

例...ページから始めるとhttp://spsite.ex/variation/site2/subsite2.1/subsite2.1.1/subsite2.1.1.3/page.aspx...

Site1
Site2
    SubSite2.1
        SubSite2.1.1
            SubSite2.1.1.1
            SubSite2.1.1.2
            SubSite2.1.1.3
                page.aspx (YOU ARE HERE)
    SubSite2.2
    Site2Page1
    Site2Page2
Site3
Site4
Site5

次に、リンクをクリックすると、次のSubSite2.1ようなものが表示されます...

Site1
Site2
    SubSite2.1 (YOU ARE HERE)
        SubSite2.1.1
    SubSite2.2
    Site2Page1
    Site2Page2
Site3
Site4
Site5

次に移動するhttp://spsite.ex/variation/site5/subsite5.1/page.aspxと、次のようなものが表示されます...

Site1
Site2
Site3
Site4
Site5
    SubSite5.1
        SubSite5.1.1
        page.aspx (YOU ARE HERE)

私は解決策を書きましが、それは私が誇りに思うべきものではないように感じます。現在のWebの祖先を除いて、子ノードを取得しないようにオーバーライドしてAspMenu、ほぼ無限大StaticDisplayLevelsに拡張してから拡張しました。PortalSiteMapProviderGetChildNode(node)

4

4 に答える 4

1

@ ScottE、この問題を解決するために使用したコードをなんとか再現できたと思います。

using System;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
using Microsoft.SharePoint.Publishing.Navigation;

namespace StackOverflow.SharePoint
{
    public class Question2602537PortalSiteMapProvider : PortalSiteMapProvider
    {

        public override SiteMapNodeCollection GetChildNodes(System.Web.SiteMapNode node)
        {
            bool expandChildNodes = false;
            if (SPContext.Current != null)
            {
                expandChildNodes = NodeIsAncestorOfCurrentNode(node);
            }

            if (expandChildNodes)
            {
                return base.GetChildNodes(node);
            }
            else
            {
                return new SiteMapNodeCollection();
            }
        }

        private bool NodeIsAncestorOfCurrentNode(System.Web.SiteMapNode node)
        {
            bool returnvalue = false;
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite thisSite = new SPSite(SPContext.Current.Site.ID))
                {
                    using (SPWeb nodeWeb = this.OpenWeb(thisSite, node))
                    {
                        using (SPWeb currentWeb = this.OpenNavWeb(thisSite))
                        {
                            returnvalue = this.AncestorDescendantWebs(nodeWeb, currentWeb);
                        }
                    }
                }
            });
            return returnvalue;
        }

        private SPWeb OpenWeb(SPSite thisSite, System.Web.SiteMapNode node)
        {
            // need to use Uri objects, as sometimes the node URL contains a query string
            // but calling OpenWeb(...) with a ? in your URL throws an exception
            // using Uri.LocalPath removes the Query String
            Uri siteUri = new Uri(thisSite.Url);
            Uri nodeUri = new Uri(siteUri, node.Url);
            return thisSite.OpenWeb(nodeUri.LocalPath.Split(new string[] { "/_" }, StringSplitOptions.RemoveEmptyEntries)[0], false);
        }

        private SPWeb OpenNavWeb(SPSite thisSite)
        {
            using (SPWeb currentWeb = thisSite.OpenWeb(this.CurrentWeb.ID))
            {
                SPWeb web = currentWeb;
                PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(web);

                // Loop all the way up the webs until we find the one which doesn't inherit
                // (there's gotta be a better way of doing this)
                while (publishingWeb.InheritCurrentNavigation &&
                    !web.ID.Equals(thisSite.RootWeb.ID))
                {
                    web = web.ParentWeb;
                    publishingWeb = PublishingWeb.GetPublishingWeb(web);
                }

                return web;
            }
        }

        private bool AncestorDescendantWebs(SPWeb ancestor, SPWeb descendant)
        {
            // check the URLs to determine if descendant is a subweb or ancestor
            // (there's gotta be a better way...)
            if ((descendant.ServerRelativeUrl + "/").ToUpper().StartsWith(ancestor.ServerRelativeUrl.ToUpper() + "/"))
            {
                return true;
            }
            return false;
        }

    }
}

おそらく最善の解決策ではありません...しかし解決策です。

于 2011-02-06T04:37:21.050 に答える
0

カスタムコード化されたソリューションを実行する場合は、HierarchicalDataBoundControlから継承するクラスを作成できます。masterpage/pagelayoutのPortalSiteMapDataSourceに接続します。これにより、出力を完全に制御でき、可能な限り最適化されます。

于 2010-12-15T15:56:48.093 に答える
0

あなたのコードはどのように見えますか...標準を使用するこのような典型的なメニューはこれSiteMapProviderよりもはるかに単純にすることはできません

public class SideMenu : Control
{
    private SiteMapNode _rootNode = SiteMap.RootNode;
    public SiteMapNode RootNode
    {
        get { return this._rootNode; }
        set { this._rootNode = value; }
    }

    public SideMenu()
    {
        ID = "SideMenu";
    }

    protected override void CreateChildControls()
    {
        var div = new HtmlGenericControl("div");
        div.Attributes.Add("id", ID);
        Controls.Add(div);

        CreateMenuNodes(RootNode, div);

        base.CreateChildControls();
    }

    protected override void Render(HtmlTextWriter writer)
    {
        if (!ChildControlsCreated)
        {
            CreateChildControls();
        }

        base.Render(writer);
    }

    private void CreateMenuNodes(SiteMapNode node, HtmlGenericControl container)
    {
        if (node.HasChildNodes)
        {
            var ul = new HtmlGenericControl("ul");
            container.Controls.Add(ul);

            foreach (SiteMapNode child in node.ChildNodes)
            {
                var li = new HtmlGenericControl("li");
                ul.Controls.Add(li);

                var a = new HtmlAnchor()
                {
                    InnerHtml = HttpUtility.HtmlEncode(child.Title),
                    Title = child.Title,
                    HRef = child.Url
                };

                li.Controls.Add(a);

                if (SiteMap.CurrentNode.IsEqualToOrDescendantOf(child))
                {
                    li.Attributes["class"] = "selected";

                    CreateMenuNodes(child, li);
                }
            }
        }
    }
}
于 2011-01-06T06:20:48.167 に答える
0

これは、はるかにエレガントな別のオプションです。 http://sharepoint2010customnavigation.blogspot.com/

于 2011-05-26T15:50:09.547 に答える