Frage

Ich versuche, das Schnellstartmenü zu konfigurieren, dass nur die Vorfahren anzuzeigen und absteigenden Knoten des aktuell ausgewählten Knoten. Das Menü muss auch alle childern des Root-Knotens anzuzeigen. Einfacher gesagt:

Bei einer Website Karte von:

RootSite

--- subsite1 = Navigation auf gesetzt "um den aktuellen Standort anzeigen, die Navigationselemente unter dem aktuellen Standort und die aktuellen Website Geschwister"

----- Heading1 = Navigation auf "Zeigen Sie die gleichen Navigationselemente wie die übergeordnete Website" gesetzt

------- Seite1 = Navigation auf "Zeigen Sie die gleichen Navigationselemente wie die übergeordnete Website" gesetzt

------- Seite 2 = Navigation auf "Zeigen Sie die gleichen Navigationselemente wie die übergeordnete Website" gesetzt

----- Heading2 = Navigation auf "Zeigen Sie die gleichen Navigationselemente wie die übergeordnete Website" gesetzt

--- SubSite2 = Navigation auf gesetzt "um den aktuellen Standort anzeigen, die Navigationselemente unter dem aktuellen Standort und die aktuellen Website Geschwister"

----- Heading1 = Navigation auf "Zeigen Sie die gleichen Navigationselemente wie die übergeordnete Website" gesetzt

Sitemap Konfiguration:

<PublishingNavigation:PortalSiteMapDataSource ID="SiteMapDS" Runat="server"
SiteMapProvider="CurrentNavSiteMapProvider" EnableViewState="true"
StartFromCurrentNode="true" ShowStartingNode="false"/>

Die erwartete und tatsächliche Verhalten des Schnellstartmenü auf subsite1 angezeigt ist:

--- subsite1

----- Heading1

------- Seite1

------- Seite 2

----- Heading2

--- SubSite2

Das erwartete Verhalten des Menüs nach dem Heading1 von SubSite2 Navigation:

--- subsite1

--- SubSite2

----- Heading1

Was ich sehe, tatsächlich nach dem Heading1 von SubSite2 Navigation:

--- subsite1

----- Heading1

------- Seite1

------- Seite 2

----- Heading2

--- SubSite2

----- Heading1

Das stimmt nicht überein, was ich erwarte, um zu sehen, ob ich die Heading1 Navigation „aufzurufen die gleiche Navigationselemente wie die übergeordneten Website“und SubSite2 wird auf‚den aktuellen Standort anzeigen, die Navigationspunkte unter dem aktuellen Standort und die aktuellen Website Geschwister‘. Ich erwarte, dass Heading1 den Navigationspunkt von SubSite2 mit dem subsite1 Artikel erben kollabierte aus dem Blick. Ich habe auch mit den verschiedenen gespielt Trim ... Attribute ohne Erfolg. Jede Hilfe wird sehr geschätzt!

War es hilfreich?

Lösung

Ich folgte @ Nat Führung in die düstere Welt Sharepoint webparts das Verhalten zu erreichen, die ich oben beschrieben. Mein Ansatz war meine eigene Version des MossMenu webpart , dass Microsoft durch das ECM Team Blog veröffentlicht. Dieser Code basiert auf der nativen AspMenu Kontrolle. Ich verwenden, um dieses Steuerelement „Intercept“ die native Sitemap injiziert durch DataSourceID Attribut im Markup und erstellen Sie eine neue XML-Datenquelle das gewünschte Verhalten zu zeigen. Ich habe die letzte Quellcode am Ende dieser wortreich Antwort enthalten. Hier sind die Bits von der Master-Seite Markup:

<%@ Register TagPrefix="myCustom" Namespace="YourCompany.CustomWebParts"
   Assembly="YourCompany.CustomWebParts, Version=1.0.0.0, Culture=neutral,
   PublicKeyToken=9f4da00116c38ec5" %>

...

<myCustom:MossMenu ID="CurrentNav" runat="server" datasourceID="SiteMapDS"
    orientation="Vertical" UseCompactMenus="true" StaticDisplayLevels="6"
    MaximumDynamicDisplayLevels="0" StaticSubMenuIndent="5" ItemWrap="false"
    AccessKey="3" CssClass="leftNav"
    SkipLinkText="<%$Resources:cms,masterpages_skiplinktext%>">
    <LevelMenuItemStyles>
        <asp:MenuItemStyle CssClass="Nav" />
        <asp:MenuItemStyle CssClass="SecNav" />
    </LevelMenuItemStyles>
    <StaticHoverStyle CssClass="leftNavHover"/>
    <StaticSelectedStyle CssClass="leftNavSelected"/>
    <DynamicMenuStyle CssClass="leftNavFlyOuts" />
    <DynamicMenuItemStyle CssClass="leftNavFlyOutsItem"/>
    <DynamicHoverStyle CssClass="leftNavFlyOutsHover"/>
</myCustom:MossMenu>

<PublishingNavigation:PortalSiteMapDataSource ID="SiteMapDS" Runat="server"
     SiteMapProvider="CurrentNavSiteMapProvider" EnableViewState="true"
     StartFromCurrentNode="true" ShowStartingNode="false"/>

...

folgte ich die ausgezeichnete Schritt-für-Schritt-Anleitung zu meinem benutzerdefinierten Webpart in den Kommentaren des MossMenu webpart bei" mittwoch September 19, 2007, 07.20 Uhr von Roel“. In meinem googeln fand ich auch etwas eine Sharepoint-Website zu konfigurieren, Ausnahmen in der gleichen schönen Art und Weise zu zeigen, dass ASP.NET tut, indem sie die web.config Änderungen hier .

Ich beschloss, mein individuelles Verhalten zu nennen „compact Menü“ so habe ich eine UseCompactMenus Eigenschaft auf dem Steuerelement. Wenn Sie dieses Attribut nicht im Markup auf true gesetzt ist, wird die Steuerung verhält sich genauso wie eine AspMenu Kontrolle.

Meine Anwendung hat den Benutzer immer von der Seite zu Hause auf dem Lageplan root starten. Ich kann die benutzerdefinierten Steuerspeicher habe den anfänglichen (komplett) Site-Map, wenn die Root-Seite angezeigt wird. Dies wird in einer statischen Zeichenfolge für die Verwendung im Customizing Verhalten gespeichert. Wenn Sie Anwendung dieser Annahme nicht folgt, wird die Kontrolle nicht funktionieren wie erwartet.

Auf der Erstanwendung Seite wird nur die direkt untergeordneten Seiten in der Root-Seite werden im Menü angezeigt. Ein Klick auf diesen Menüknoten werden alle untergeordneten Knoten unter ihm öffnen, aber hält die Geschwister-Knoten „geschlossen“. Wenn Sie auf einem der anderen Geschwister-Knoten klicken, bricht es den aktuellen Knoten und es öffnet sich die neu ausgewählten Knoten. Das ist es, genießen !!

using System;
using System.Text;
using System.ComponentModel;
using System.Collections.Generic;
using System.Security.Permissions;
using System.Xml;
using System.Xml.Serialization;

using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.Design.WebControls;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Security;

namespace YourCompany.CustomWebParts
{
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
    [SharePointPermission(SecurityAction.InheritanceDemand, ObjectModel = true)]
    [Designer(typeof(MossMenuDesigner))]
    [ToolboxData("<{0}:MossMenu runat=\"server\" />")]
    public class MossMenu : System.Web.UI.WebControls.Menu
    {
        private string idPrefix;

        // a url->menuItem dictionary
        private Dictionary<string, System.Web.UI.WebControls.MenuItem> menuItemDictionary =
            new Dictionary<string, System.Web.UI.WebControls.MenuItem>(StringComparer.OrdinalIgnoreCase);

        private bool customSelectionEnabled = true;
        private bool selectStaticItemsOnly = true;

        private bool performTargetBinding = true;

        //** Variables used for compact menu behavior **//
        private bool useCompactMenus = false;
        private static bool showStartingNode;
        private static string originalSiteMap;

        /// <summary>
        /// Controls whether or not the control performs compacting of the site map to display only ancestor and child nodes of the selected and first level root childern.
        /// </summary>
        [Category("Behavior")]
        public bool UseCompactMenus
        {
            get
            {
                return this.useCompactMenus;
            }
            set
            {
                this.useCompactMenus = value;
            }
        }

        /// <summary>
        /// Controls whether or not the control performs custom selection/highlighting.
        /// </summary>
        [Category("Behavior")]
        public bool CustomSelectionEnabled
        {
            get
            {
                return this.customSelectionEnabled;
            }
            set
            {
                this.customSelectionEnabled = value;
            }
        }

        /// <summary>
        /// Controls whether only static items may be selected or if
        /// dynamic (fly-out) items may be selected too.
        /// </summary>
        [Category("Behavior")]
        public bool SelectStaticItemsOnly
        {
            get
            {
                return this.selectStaticItemsOnly;
            }
            set
            {
                this.selectStaticItemsOnly = value;
            }
        }

        /// <summary>
        /// Controls whether or not to bind the Target property of any menu
        /// items to the Target property in the SiteMapNode's Attributes
        /// collection.
        /// </summary>
        [Category("Behavior")]
        public bool PerformTargetBinding
        {
            get
            {
                return this.performTargetBinding;
            }
            set
            {
                this.performTargetBinding = value;
            }
        }

        /// <summary>
        /// Gets the ClientID of this control. 
        /// </summary>
        public override string ClientID
        {
            [SharePointPermission(SecurityAction.Demand, ObjectModel = true)]
            get
            {
                if (this.idPrefix == null)
                {
                    this.idPrefix = SPUtility.GetNewIdPrefix(this.Context);
                }

                return SPUtility.GetShortId(this.idPrefix, this);
            }
        }

        [SharePointPermission(SecurityAction.Demand, ObjectModel = true)]
        protected override void OnMenuItemDataBound(MenuEventArgs e)
        {
            base.OnMenuItemDataBound(e);

            if (this.customSelectionEnabled)
            {
                // store in the url->item dictionary
                this.menuItemDictionary[e.Item.NavigateUrl] = e.Item;
            }

            if (this.performTargetBinding)
            {
                // try to bind to the Target property if the data item is a SiteMapNode
                SiteMapNode smn = e.Item.DataItem as SiteMapNode;
                if (smn != null)
                {
                    string target = smn["Target"];
                    if (!string.IsNullOrEmpty(target))
                    {
                        e.Item.Target = target;
                    }
                }
            }
        }

        /// <id guid="08e034e7-5872-4a31-a771-84cac1dcd53d" />
        /// <owner alias="MarkWal">
        /// </owner>
        [SharePointPermission(SecurityAction.Demand, ObjectModel = true)]
        protected override void OnPreRender(System.EventArgs e)
        {

            SiteMapDataSource dataSource = this.GetDataSource() as SiteMapDataSource;
            SiteMapProvider provider = (dataSource != null) ? dataSource.Provider : null;

            if (useCompactMenus && dataSource != null && provider != null)
            {
                showStartingNode = dataSource.ShowStartingNode;

                SiteMapNodeCollection rootChildNodes = provider.RootNode.ChildNodes;

                if (provider.CurrentNode.Equals(provider.RootNode))
                {
                    //** Store original site map for future use in compacting menus **//
                    if (originalSiteMap == null)
                    {
                        //Store original SiteMapXML for future adjustments:
                        XmlDocument newSiteMapDoc = new XmlDocument();
                        newSiteMapDoc.LoadXml("<?xml version='1.0' ?>"
                            + "<siteMapNode title='" + provider.RootNode.Title
                            + "' url='" + provider.RootNode.Url
                            + "' />");

                        foreach (SiteMapNode node in rootChildNodes)
                        {
                            XmlNode newNode = GetXmlSiteMapNode(newSiteMapDoc.DocumentElement, node);

                            newSiteMapDoc.DocumentElement.AppendChild(newNode);

                            //Create XML for all the child nodes for selected menu item:
                            NavigateSiteMap(newNode, node);
                        }

                        originalSiteMap = newSiteMapDoc.OuterXml;
                    }

                    //This is set to only display the child nodes of the root node on first view:
                    this.StaticDisplayLevels = 1;
                }
                else
                {
                    //
                    //Adjust site map for this page
                    //
                    XmlDocument newSiteMapDoc = InitializeNewSiteMapXml(provider, rootChildNodes);

                    //Clear the current default site map:
                    this.DataSourceID = null;

                    //Create the new site map data source
                    XmlDataSource newSiteMap = new XmlDataSource();
                    newSiteMap.ID = "XmlDataSource1";
                    newSiteMap.EnableCaching = false; //Required to prevent redisplay of the previous menu

                    //Add bindings for dynamic site map:
                    MenuItemBindingCollection bindings = this.DataBindings;
                    bindings.Clear();

                    MenuItemBinding binding = new MenuItemBinding();
                    binding.DataMember = "siteMapNode";
                    binding.TextField = "title";
                    binding.Text = "title";
                    binding.NavigateUrlField = "url";
                    binding.NavigateUrl = "url";
                    binding.ValueField = "url";
                    binding.Value = "url";

                    bindings.Add(binding);

                    //Bind menu to new site map:
                    this.DataSource = newSiteMap;

                    //Assign the newly created dynamic site map:
                    ((XmlDataSource)this.DataSource).Data = newSiteMapDoc.OuterXml;

                    /** this expression removes the root if initialized: **/
                    if (!showStartingNode)
                        ((XmlDataSource)this.DataSource).XPath = "/siteMapNode/siteMapNode";

                    /** Re-initialize menu data source with new site map: **/
                    this.DataBind();

                    /** Find depth of current node: **/
                    int depth = 0;
                    SiteMapNode currNode = provider.CurrentNode;
                    do
                    {
                        depth++;
                        currNode = currNode.ParentNode;
                    }
                    while (currNode != null);

                    //Set the StaticDisplayLevels to match the current depth:
                    if (depth >= this.StaticDisplayLevels)
                        this.StaticDisplayLevels = depth;
                }
            }

            base.OnPreRender(e);

            // output some script to override the default menu flyout behaviour; this helps to avoid
            // intermittent "Operation Aborted" errors
            Page.ClientScript.RegisterStartupScript(
                typeof(MossMenu),
                "overrideMenu_HoverStatic",
                "if (typeof(overrideMenu_HoverStatic) == 'function' && typeof(Menu_HoverStatic) == 'function')\n" +
                "{\n" +
                    "_spBodyOnLoadFunctionNames.push('enableFlyoutsAfterDelay');\n" +
                    "Menu_HoverStatic = overrideMenu_HoverStatic;\n" +
                "}\n",
                true);

            // output some script to avoid a known issue with SSL Termination and the ASP.NET
            // Menu implementation. http://support.microsoft.com/?id=910444
            Page.ClientScript.RegisterStartupScript(
                typeof(MossMenu),
                "MenuHttpsWorkaround_" + this.ClientID,
                this.ClientID + "_Data.iframeUrl='/_layouts/images/blank.gif';",
                true);

            // adjust the fly-out indicator arrow direction for locale if not already set
            if (this.Orientation == System.Web.UI.WebControls.Orientation.Vertical &&
                ((string.IsNullOrEmpty(this.StaticPopOutImageUrl) && this.StaticEnableDefaultPopOutImage) ||
                    (string.IsNullOrEmpty(this.DynamicPopOutImageUrl) && this.DynamicEnableDefaultPopOutImage)))
            {
                SPWeb currentWeb = SPContext.Current.Web;
                if (currentWeb != null)
                {
                    uint localeId = currentWeb.Language;

                    bool isBidiWeb = SPUtility.IsRightToLeft(currentWeb, currentWeb.Language);

                    string arrowUrl = "/_layouts/images/" + (isBidiWeb ? "largearrowleft.gif" : "largearrowright.gif");

                    if (string.IsNullOrEmpty(this.StaticPopOutImageUrl) && this.StaticEnableDefaultPopOutImage)
                    {
                        this.StaticPopOutImageUrl = arrowUrl;
                    }
                    if (string.IsNullOrEmpty(this.DynamicPopOutImageUrl) && this.DynamicEnableDefaultPopOutImage)
                    {
                        this.DynamicPopOutImageUrl = arrowUrl;
                    }
                }
            }

            if (provider == null)
            {
                // if we're not attached to a SiteMapDataSource we'll just leave everything alone
                return;
            }
            else if (this.customSelectionEnabled)
            {
                MenuItem selectedMenuItem = this.SelectedItem;
                SiteMapNode currentNode = provider.CurrentNode;

                // if no menu item is presently selected, we need to work our way up from the current 
                // node until we can find a node in the menu item dictionary
                while (selectedMenuItem == null && currentNode != null)
                {
                    this.menuItemDictionary.TryGetValue(currentNode.Url, out selectedMenuItem);

                    currentNode = currentNode.ParentNode;
                }

                if (this.selectStaticItemsOnly)
                {
                    // only static items may be selected, keep moving up until we find an item
                    // that falls within the static range
                    while (selectedMenuItem != null && selectedMenuItem.Depth >= this.StaticDisplayLevels)
                    {
                        selectedMenuItem = selectedMenuItem.Parent;
                    }

                    // if we found an item to select, go ahead and select (highlight) it
                    if (selectedMenuItem != null && selectedMenuItem.Selectable)
                    {
                        selectedMenuItem.Selected = true;
                    }
                }
            }
        }

        private XmlDocument InitializeNewSiteMapXml(SiteMapProvider provider, SiteMapNodeCollection rootChildNodes)
        {
            /** Find the level 1 ancestor node of the current node: **/
            SiteMapNode levelOneAncestorOfSelectedNode = null;
            SiteMapNode currNode = provider.CurrentNode;
            do
            {
                levelOneAncestorOfSelectedNode = (currNode.ParentNode == null ? levelOneAncestorOfSelectedNode : currNode);
                currNode = currNode.ParentNode;
            }
            while (currNode != null);

            /** Initialize base SiteMapXML **/
            XmlDocument newSiteMapDoc = new XmlDocument();
            newSiteMapDoc.LoadXml(originalSiteMap);

            /** Prune out the childern nodes that shouldn't display: **/
            currNode = provider.CurrentNode;
            do
            {
                if (currNode.ParentNode != null)
                {
                    SiteMapNodeCollection currNodeSiblings = currNode.ParentNode.ChildNodes;
                    foreach (SiteMapNode siblingNode in currNodeSiblings)
                    {
                        if (siblingNode.HasChildNodes)
                        {
                            if (provider.CurrentNode.Equals(siblingNode))
                            {
                                //Remove all the childerns child nodes from display:
                                SiteMapNodeCollection currNodesChildren = siblingNode.ChildNodes;
                                foreach (SiteMapNode childNode in currNodesChildren)
                                {
                                    XmlNode currentXmNode = GetCurrentXmlNode(newSiteMapDoc, childNode);

                                    DeleteChildNodes(currentXmNode);
                                }
                            }
                            else if (!provider.CurrentNode.IsDescendantOf(siblingNode)
                                && !levelOneAncestorOfSelectedNode.Equals(siblingNode))
                            {
                                XmlNode currentXmNode = GetCurrentXmlNode(newSiteMapDoc, siblingNode);

                                DeleteChildNodes(currentXmNode);
                            }
                        }
                    }
                }

                currNode = currNode.ParentNode;
            }
            while (currNode != null);

            return newSiteMapDoc;
        }

        private XmlNode GetCurrentXmlNode(XmlDocument newSiteMapDoc, SiteMapNode node)
        {
            //Find this node in the original site map:
            XmlNode currentXmNode = newSiteMapDoc.DocumentElement.SelectSingleNode(
                "//siteMapNode[@url='"
                + node.Url
                + "']");
            return currentXmNode;
        }

        private void DeleteChildNodes(XmlNode currentXmNode)
        {
            if (currentXmNode != null && currentXmNode.HasChildNodes)
            {
                //Remove child nodes:
                XmlNodeList xmlNodes = currentXmNode.ChildNodes;
                int lastNodeIndex = xmlNodes.Count - 1;
                for (int i = lastNodeIndex; i >= 0; i--)
                {
                    currentXmNode.RemoveChild(xmlNodes[i]);
                }
            }
        }
        private XmlNode GetXmlSiteMapNode(XmlNode currentDocumentNode, SiteMapNode currentNode)
        {
            XmlElement newNode = currentDocumentNode.OwnerDocument.CreateElement("siteMapNode");

            XmlAttribute newAttr = currentDocumentNode.OwnerDocument.CreateAttribute("title");
            newAttr.InnerText = currentNode.Title;
            newNode.Attributes.Append(newAttr);

            newAttr = currentDocumentNode.OwnerDocument.CreateAttribute("url");
            newAttr.InnerText = currentNode.Url;
            newNode.Attributes.Append(newAttr);

            return newNode;
        }

        private void NavigateSiteMap(XmlNode currentDocumentNode, SiteMapNode currentNode)
        {
            foreach (SiteMapNode node in currentNode.ChildNodes)
            {
                //Add this node to structure:
                XmlNode newNode = GetXmlSiteMapNode(currentDocumentNode, node);
                currentDocumentNode.AppendChild(newNode);

                if (node.HasChildNodes)
                {
                    //Make a recursive call to add any child nodes:
                    NavigateSiteMap(newNode, node);
                }
            }
        }
    }

    [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2117:AptcaTypesShouldOnlyExtendAptcaBaseTypes")]
    public sealed class MossMenuDesigner : MenuDesigner
    {
        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
        protected override void DataBind(BaseDataBoundControl dataBoundControl)
        {
            try
            {
                dataBoundControl.DataBind();
            }
            catch
            {
                base.DataBind(dataBoundControl);
            }
        }

        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
        public override string GetDesignTimeHtml()
        {
            System.Web.UI.WebControls.Menu menu = (System.Web.UI.WebControls.Menu)ViewControl;
            int oldDisplayLevels = menu.MaximumDynamicDisplayLevels;
            string designTimeHtml = string.Empty;

            try
            {
                menu.MaximumDynamicDisplayLevels = 0;

                // ASP.NET MenuDesigner has some dynamic/static item trick in design time
                // to show dynamic item in design time. We only want to show preview without
                // dynamic menu items.
                designTimeHtml = base.GetDesignTimeHtml();
            }
            catch (Exception e)
            {
                designTimeHtml = GetErrorDesignTimeHtml(e);
            }
            finally
            {
                menu.MaximumDynamicDisplayLevels = oldDisplayLevels;
            }

            return designTimeHtml;
        }
    }
}

Andere Tipps

Ich persönlich mag es nicht, die HTML, die das Standardmenü (Tabelle basierte Layout) zur Verfügung stellt. Zum Glück hat sich die Sharepoint Team den Code für die Freigabe Kontrolle .

Was wir getan haben, ist, dass Code in einem Projekt zu schließen und die Methode macht außer Kraft gesetzt hat, zu tun, was wir wollen. Dies gibt Ihnen die Flexibilität, um die genaue Beziehung zwischen den Eltern zu definieren, als auch sein Display muss wie die Stile auf alle divs Einstellung, die Sie erstellen.

Auf der anderen Seite Sie jetzt Codierung, nicht zu konfigurieren und eine Änderung muss die Masterseite vorgenommen werden Sie verwenden, um die Steuerung zu verwenden.

Es lohnt sich meiner Meinung nach. Dies ist nun ein Standard ändern wir für jede Website.

Der Ansatz, den wir verwenden, um die zu erreichen, beeinflussen Sie suchen, war die CSS freundliche Steuerung Adapter zu verwenden . Die Adapter ändern Sie den HTML-Code, ohne Änderung der Steuerelemente, die Sie auf Ihren Seiten verwendet gerendert wird. Möglicherweise müssen Sie das Menü Adapter ein wenig, um zwicken das gewünschte Layout zu erhalten. Es dauerte nur ein paar Zeilen Code für uns. Sobald Sie diese Arbeits erhalten, können Sie CSS verwenden, das Verhalten zu erhalten, die Sie beschreiben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top