SiteMapPath.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / xsp / System / Web / UI / WebControls / SiteMapPath.cs / 1 / SiteMapPath.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI.WebControls { 
 
    using System;
    using System.Collections; 
    using System.ComponentModel;
    using System.Security.Permissions;
    using System.Web;
    using System.Web.UI; 
    using System.Web.Util;
 
 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [
    Designer("System.Web.UI.Design.WebControls.SiteMapPathDesigner, " + AssemblyRef.SystemDesign)
    ]
 
    public class SiteMapPath : CompositeControl {
 
        private const string _defaultSeparator = " > "; 
        private const string _afterSiteMapPathMark = "_SkipLink";
 
        private static readonly object _eventItemCreated = new object();
        private static readonly object _eventItemDataBound = new object();
        private SiteMapProvider _provider = null;
 
        private Style _currentNodeStyle;
        private Style _rootNodeStyle; 
        private Style _nodeStyle; 
        private Style _pathSeparatorStyle;
 
        private Style _mergedCurrentNodeStyle;
        private Style _mergedRootNodeStyle;

        private ITemplate _currentNodeTemplate; 
        private ITemplate _rootNodeTemplate;
        private ITemplate _nodeTemplate; 
        private ITemplate _pathSeparatorTemplate; 

 
        public SiteMapPath() {
        }

 
        [
        DefaultValue(null), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty), 
        WebCategory("Styles"),
        WebSysDescription(SR.SiteMapPath_CurrentNodeStyle)
        ]
        public Style CurrentNodeStyle { 
            get {
                if (_currentNodeStyle == null) { 
                    _currentNodeStyle = new Style(); 
                    if (IsTrackingViewState) {
                        ((IStateManager)_currentNodeStyle).TrackViewState(); 
                    }
                }

                return _currentNodeStyle; 
            }
        } 
 

        ///  
        /// Gets or sets the  that defines how the current node is rendered. 
        /// 
        [
        Browsable(false), 
        DefaultValue(null),
        PersistenceMode(PersistenceMode.InnerProperty), 
        TemplateContainer(typeof(SiteMapNodeItem)), 
        WebSysDescription(SR.SiteMapPath_CurrentNodeTemplate)
        ] 
        public virtual ITemplate CurrentNodeTemplate {
            get {
                return _currentNodeTemplate;
            } 
            set {
                _currentNodeTemplate = value; 
            } 
        }
 

        [
        DefaultValue(null),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty), 
        WebCategory("Styles"), 
        WebSysDescription(SR.SiteMapPath_NodeStyle)
        ] 
        public Style NodeStyle {
            get {
                if (_nodeStyle == null) {
                    _nodeStyle = new Style(); 
                    if (IsTrackingViewState) {
                        ((IStateManager)_nodeStyle).TrackViewState(); 
                    } 
                }
 
                return _nodeStyle;
            }
        }
 

        ///  
        /// Gets or sets the  that defines how the parent node is rendered.  
        /// 
        [ 
        Browsable(false),
        DefaultValue(null),
        PersistenceMode(PersistenceMode.InnerProperty),
        TemplateContainer(typeof(SiteMapNodeItem)), 
        WebSysDescription(SR.SiteMapPath_NodeTemplate)
        ] 
        public virtual ITemplate NodeTemplate { 
            get {
                return _nodeTemplate; 
            }
            set {
                _nodeTemplate = value;
            } 
        }
 
 
        /// 
        ///    Indicates the number of parent nodes to display. 
        /// 
        [
        DefaultValue(-1),
        Themeable(false), 
        WebCategory("Behavior"),
        WebSysDescription(SR.SiteMapPath_ParentLevelsDisplayed) 
        ] 
        public virtual int ParentLevelsDisplayed {
            get{ 
                object o = ViewState["ParentLevelsDisplayed"];
                if (o == null) {
                    return -1;
                } 
                return (int)o;
            } 
            set { 
                if (value < -1) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["ParentLevelsDisplayed"] = value;
            }
        } 

 
        [ 
        DefaultValue(PathDirection.RootToCurrent),
        WebCategory("Appearance"), 
        WebSysDescription(SR.SiteMapPath_PathDirection)
        ]
        public virtual PathDirection PathDirection {
            get { 
                object o = ViewState["PathDirection"];
                if (o == null) { 
                    return PathDirection.RootToCurrent; 
                }
                return (PathDirection)o; 
            }
            set {
                if ((value < PathDirection.RootToCurrent) || (value > PathDirection.CurrentToRoot)) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["PathDirection"] = value; 
            } 
        }
 

        [
        DefaultValue(_defaultSeparator),
        Localizable(true), 
        WebCategory("Appearance"),
        WebSysDescription(SR.SiteMapPath_PathSeparator) 
        ] 
        public virtual string PathSeparator {
            get { 
                string s = (string)ViewState["PathSeparator"];
                if (s == null) {
                    return _defaultSeparator;
                } 
                return s;
            } 
            set { 
                ViewState["PathSeparator"] = value;
            } 
        }


        [ 
        DefaultValue(null),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty),
        WebCategory("Styles"), 
        WebSysDescription(SR.SiteMapPath_PathSeparatorStyle)
        ]
        public Style PathSeparatorStyle {
            get { 
                if (_pathSeparatorStyle == null) {
                    _pathSeparatorStyle = new Style(); 
                    if (IsTrackingViewState) { 
                        ((IStateManager)_pathSeparatorStyle).TrackViewState();
                    } 
                }

                return _pathSeparatorStyle;
            } 
        }
 
 
        /// 
        /// Gets or sets the  that defines how the path Separator is rendered.  
        /// 
        [
        Browsable(false),
        DefaultValue(null), 
        PersistenceMode(PersistenceMode.InnerProperty),
        TemplateContainer(typeof(SiteMapNodeItem)), 
        WebSysDescription(SR.SiteMapPath_PathSeparatorTemplate) 
        ]
        public virtual ITemplate PathSeparatorTemplate { 
            get {
                return _pathSeparatorTemplate;
            }
            set { 
                _pathSeparatorTemplate = value;
            } 
        } 

 
        [
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        WebSysDescription(SR.SiteMapPath_Provider) 
        ]
        public SiteMapProvider Provider { 
            get { 
                // Designer must specify a provider, as code below access runtime config
                if (_provider != null || DesignMode) 
                    return _provider;

                // If not specified, use the default provider.
                if (String.IsNullOrEmpty(SiteMapProvider)) { 
                    _provider = SiteMap.Provider;
 
                    if (_provider == null) { 
                        throw new HttpException(SR.GetString(SR.SiteMapDataSource_DefaultProviderNotFound));
                    } 
                }
                else {
                    _provider = SiteMap.Providers[SiteMapProvider];
 
                    if (_provider == null) {
                        throw new HttpException(SR.GetString(SR.SiteMapDataSource_ProviderNotFound, SiteMapProvider)); 
                    } 
                }
 
                return _provider;
            }
            set {
                _provider = value; 
            }
        } 
 

        [ 
        DefaultValue(false),
        WebCategory("Appearance"),
        WebSysDescription(SR.SiteMapPath_RenderCurrentNodeAsLink)
        ] 
        public virtual bool RenderCurrentNodeAsLink {
            get { 
                object o = ViewState["RenderCurrentNodeAsLink"]; 
                if (o == null) {
                    return false; 
                }

                return (bool)o;
            } 
            set {
                ViewState["RenderCurrentNodeAsLink"] = value; 
            } 
        }
 

        [
        DefaultValue(null),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty), 
        WebCategory("Styles"), 
        WebSysDescription(SR.SiteMapPath_RootNodeStyle)
        ] 
        public Style RootNodeStyle {
            get {
                if (_rootNodeStyle == null) {
                    _rootNodeStyle = new Style(); 
                    if (IsTrackingViewState) {
                        ((IStateManager)_rootNodeStyle).TrackViewState(); 
                    } 
                }
 
                return _rootNodeStyle;
            }
        }
 

        ///  
        /// Gets or sets the  that defines how the root node is rendered.  
        /// 
        [ 
        Browsable(false),
        DefaultValue(null),
        PersistenceMode(PersistenceMode.InnerProperty),
        TemplateContainer(typeof(SiteMapNodeItem)), 
        WebSysDescription(SR.SiteMapPath_RootNodeTemplate)
        ] 
        public virtual ITemplate RootNodeTemplate { 
            get {
                return _rootNodeTemplate; 
            }
            set {
                _rootNodeTemplate = value;
            } 
        }
 
 
        [
        Localizable(true), 
        WebCategory("Accessibility"),
        WebSysDefaultValue(SR.SiteMapPath_Default_SkipToContentText),
        WebSysDescription(SR.SiteMapPath_SkipToContentText)
        ] 
        public virtual String SkipLinkText {
            get { 
                string s = ViewState["SkipLinkText"] as String; 
                return s == null ? SR.GetString(SR.SiteMapPath_Default_SkipToContentText) : s;
            } 
            set {
                ViewState["SkipLinkText"] = value;
            }
        } 

 
        [ 
        DefaultValue(true),
        Themeable(false), 
        WebCategory("Behavior"),
        WebSysDescription(SR.SiteMapPath_ShowToolTips)
        ]
        public virtual bool ShowToolTips { 
            get {
                object o = ViewState["ShowToolTips"]; 
                if (o == null) { 
                    return true;
                } 

                return (bool)o;
            }
            set { 
                ViewState["ShowToolTips"] = value;
            } 
        } 

 
        [
        DefaultValue(""),
        Themeable(false),
        WebCategory("Behavior"), 
        WebSysDescription(SR.SiteMapPath_SiteMapProvider)
        ] 
        public virtual string SiteMapProvider { 
            get {
                string provider = ViewState["SiteMapProvider"] as string; 
                return (provider == null) ? String.Empty : provider;
            }
            set {
                ViewState["SiteMapProvider"] = value; 
                _provider = null;
            } 
        } 

 
        [
        WebCategory("Action"),
        WebSysDescription(SR.DataControls_OnItemCreated)
        ] 
        public event SiteMapNodeItemEventHandler ItemCreated {
            add { 
                Events.AddHandler(_eventItemCreated, value); 
            }
            remove { 
                Events.RemoveHandler(_eventItemCreated, value);
            }
        }
 

        ///  
        /// Occurs when an item is databound within a  control tree. 
        /// 
        [ 
        WebCategory("Action"),
        WebSysDescription(SR.SiteMapPath_OnItemDataBound)
        ]
        public event SiteMapNodeItemEventHandler ItemDataBound { 
            add {
                Events.AddHandler(_eventItemDataBound, value); 
            } 
            remove {
                Events.RemoveHandler(_eventItemDataBound, value); 
            }
        }

 
        /// 
        ///  
        ///  
        protected internal override void CreateChildControls() {
            Controls.Clear(); 
            CreateControlHierarchy();
            ClearChildState();
        }
 

        ///  
        ///    A protected method. Creates a control hierarchy based on current sitemap OM. 
        /// 
        protected virtual void CreateControlHierarchy() { 
            if (Provider == null)
                return;

            int index = 0; 

            CreateMergedStyles(); 
 
            SiteMapNode currentNode = Provider.GetCurrentNodeAndHintAncestorNodes(-1);
            if (currentNode != null) { 
                SiteMapNode parentNode = currentNode.ParentNode;
                if (parentNode != null) {
                    CreateControlHierarchyRecursive(ref index, parentNode, ParentLevelsDisplayed);
                } 

                CreateItem(index++, SiteMapNodeItemType.Current, currentNode); 
            } 
        }
 
        private void CreateControlHierarchyRecursive(ref int index, SiteMapNode node, int parentLevels) {
            if (parentLevels == 0)
                return;
 
            SiteMapNode parentNode = node.ParentNode;
            if (parentNode != null) { 
                CreateControlHierarchyRecursive(ref index, parentNode, parentLevels - 1); 
                CreateItem(index++, SiteMapNodeItemType.Parent, node);
            } 
            else {
                CreateItem(index++, SiteMapNodeItemType.Root, node);
            }
 
            CreateItem(index, SiteMapNodeItemType.PathSeparator , null);
        } 
 
        private SiteMapNodeItem CreateItem(int itemIndex, SiteMapNodeItemType itemType, SiteMapNode node) {
            SiteMapNodeItem item = new SiteMapNodeItem(itemIndex, itemType); 

            int index = (PathDirection == PathDirection.CurrentToRoot? 0 : -1);

            SiteMapNodeItemEventArgs e = new SiteMapNodeItemEventArgs(item); 

            //Add sitemap nodes so that they are accessible during events. 
            item.SiteMapNode = node; 
            InitializeItem(item);
 
            // Notify items
            OnItemCreated(e);

            // Add items based on PathDirection. 
            Controls.AddAt(index, item);
 
            // Databind. 
            item.DataBind();
 
            // Notify items.
            OnItemDataBound(e);

            item.SiteMapNode = null; 

            // SiteMapNodeItem is dynamically created each time, don't track viewstate. 
            item.EnableViewState = false; 

            return item; 
        }

        private void CopyStyle(Style toStyle, Style fromStyle) {
            Debug.Assert(toStyle != null); 

            // Review: How to change the default value of Font.Underline? 
            if (fromStyle != null && fromStyle.IsSet(System.Web.UI.WebControls.Style.PROP_FONT_UNDERLINE)) 
                toStyle.Font.Underline = fromStyle.Font.Underline;
 
            toStyle.CopyFrom(fromStyle);
        }

        private void CreateMergedStyles() { 
            _mergedCurrentNodeStyle = new Style();
            CopyStyle(_mergedCurrentNodeStyle, _nodeStyle); 
            CopyStyle(_mergedCurrentNodeStyle, _currentNodeStyle); 

            _mergedRootNodeStyle = new Style(); 
            CopyStyle(_mergedRootNodeStyle, _nodeStyle);
            CopyStyle(_mergedRootNodeStyle, _rootNodeStyle);
        }
 

        ///  
        ///  
        /// Overriden to handle our own databinding.
        ///  
        public override void DataBind() {
            // do our own databinding
            OnDataBinding(EventArgs.Empty);
 
            // contained items will be databound after they have been created,
            // so we don't want to walk the hierarchy here. 
        } 

 
        /// 
        /// A protected method. Populates iteratively the specified  with a
        ///    sub-hierarchy of child controls.
        ///  
        protected virtual void InitializeItem(SiteMapNodeItem item) {
            Debug.Assert(_mergedCurrentNodeStyle != null && _mergedRootNodeStyle != null); 
 
            ITemplate template = null;
            Style style = null; 
            SiteMapNodeItemType itemType = item.ItemType;
            SiteMapNode node = item.SiteMapNode;

            switch (itemType) { 
                case SiteMapNodeItemType.Root :
                    template = RootNodeTemplate != null? RootNodeTemplate : NodeTemplate; 
                    style = _mergedRootNodeStyle; 
                    break;
 
                case SiteMapNodeItemType.Parent :
                    template = NodeTemplate;
                    style = _nodeStyle;
                    break; 

                case SiteMapNodeItemType.Current : 
                    template = CurrentNodeTemplate != null? CurrentNodeTemplate : NodeTemplate; 
                    style = _mergedCurrentNodeStyle;
                    break; 

                case SiteMapNodeItemType.PathSeparator :
                    template = PathSeparatorTemplate;
                    style = _pathSeparatorStyle; 
                    break;
            } 
 
            if (template == null) {
                if (itemType == SiteMapNodeItemType.PathSeparator) { 
                    Literal separatorLiteral = new Literal();
                    separatorLiteral.Mode = LiteralMode.Encode;
                    separatorLiteral.Text = PathSeparator;
                    item.Controls.Add(separatorLiteral); 
                    item.ApplyStyle(style);
                } 
                else if (itemType == SiteMapNodeItemType.Current && !RenderCurrentNodeAsLink) { 
                    Literal currentNodeLiteral = new Literal();
                    currentNodeLiteral.Mode = LiteralMode.Encode; 
                    currentNodeLiteral.Text = node.Title;
                    item.Controls.Add(currentNodeLiteral);
                    item.ApplyStyle(style);
                } 
                else {
                    HyperLink link = new HyperLink(); 
 
                    if (style != null && style.IsSet(System.Web.UI.WebControls.Style.PROP_FONT_UNDERLINE))
                        link.Font.Underline = style.Font.Underline; 

                    link.EnableTheming = false;
                    link.Enabled = this.Enabled;
                    // VSWhidbey 281869 Don't modify input when url pointing to unc share 
                    if (node.Url.StartsWith("\\\\", StringComparison.Ordinal)) {
                        link.NavigateUrl = ResolveClientUrl(HttpUtility.UrlPathEncode(node.Url)); 
                    } 
                    else {
                        link.NavigateUrl = Context != null? 
                            Context.Response.ApplyAppPathModifier(ResolveClientUrl(HttpUtility.UrlPathEncode(node.Url))) : node.Url;
                    }
                    link.Text = HttpUtility.HtmlEncode(node.Title);
                    if (ShowToolTips) 
                        link.ToolTip = node.Description;
                    item.Controls.Add(link); 
                    link.ApplyStyle(style); 
                }
            } 
            else {
                template.InstantiateIn(item);
                item.ApplyStyle(style);
            } 
        }
 
 
        /// 
        ///  
        /// Loads a saved state of the . 
        /// 
        protected override void LoadViewState(object savedState) {
            if (savedState != null) { 
                object[] myState = (object[])savedState;
 
                Debug.Assert(myState.Length == 5); 

                base.LoadViewState(myState[0]); 

                if (myState[1] != null)
                    ((IStateManager)CurrentNodeStyle).LoadViewState(myState[1]);
 
                if (myState[2] != null)
                    ((IStateManager)NodeStyle).LoadViewState(myState[2]); 
 
                if (myState[3] != null)
                    ((IStateManager)RootNodeStyle).LoadViewState(myState[3]); 

                if (myState[4] != null)
                    ((IStateManager)PathSeparatorStyle).LoadViewState(myState[4]);
            } 
            else {
                base.LoadViewState(null); 
            } 
        }
 

        /// 
        /// 
        /// A protected method. Raises the  event. 
        /// 
        protected override void OnDataBinding(EventArgs e) { 
            base.OnDataBinding(e); 

            // reset the control state 
            Controls.Clear();
            ClearChildState();

            CreateControlHierarchy(); 
            ChildControlsCreated = true;
        } 
 

        ///  
        /// A protected method. Raises the  event.
        /// 
        protected virtual void OnItemCreated(SiteMapNodeItemEventArgs e) {
            SiteMapNodeItemEventHandler onItemCreatedHandler = 
                (SiteMapNodeItemEventHandler)Events[_eventItemCreated];
            if (onItemCreatedHandler != null) { 
                onItemCreatedHandler(this, e); 
            }
        } 


        /// 
        /// A protected method. Raises the  
        /// event.
        ///  
        protected virtual void OnItemDataBound(SiteMapNodeItemEventArgs e) { 
            SiteMapNodeItemEventHandler onItemDataBoundHandler =
                (SiteMapNodeItemEventHandler)Events[_eventItemDataBound]; 
            if (onItemDataBoundHandler != null) {
                onItemDataBoundHandler(this, e);
            }
        } 

 
        ///  
        /// 
        protected internal override void Render(HtmlTextWriter writer) { 
            // Copied from CompositeControl.cs
            if (DesignMode) {
                ChildControlsCreated = false;
                EnsureChildControls(); 
            }
 
            base.Render(writer); 
        }
 

        /// 
        ///     Adds the SkipToContextText.
        ///  

        protected internal override void RenderContents(HtmlTextWriter writer) { 
            // Only render the accessibility link at runtime. 
            bool accessibilityMode = !String.IsNullOrEmpty(SkipLinkText) && !DesignMode;
 
            String href = ClientID + _afterSiteMapPathMark;

            if (accessibilityMode) {
                //  
                writer.AddAttribute(HtmlTextWriterAttribute.Href, "#" + href);
                writer.RenderBeginTag(HtmlTextWriterTag.A); 
 
                // skipToContentText
                writer.AddAttribute(HtmlTextWriterAttribute.Alt, SkipLinkText); 
                writer.AddAttribute(HtmlTextWriterAttribute.Height, "0");
                writer.AddAttribute(HtmlTextWriterAttribute.Width, "0");
                writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "0px");
                writer.AddAttribute(HtmlTextWriterAttribute.Src, SpacerImageUrl); 
                writer.RenderBeginTag(HtmlTextWriterTag.Img);
                writer.RenderEndTag(); 
 
                // 
                writer.RenderEndTag(); 
            }

            base.RenderContents(writer);
 
            if (accessibilityMode) {
                //  
                writer.AddAttribute(HtmlTextWriterAttribute.Id, href); // XHTML 1.1 needs id instead of name 
                writer.RenderBeginTag(HtmlTextWriterTag.A);
                writer.RenderEndTag(); 
            }
        }

 
        /// 
        ///  
        /// Stores the state of the System.Web.UI.WebControls.SiteMapPath. 
        /// 
        protected override object SaveViewState() { 
            object[] myState = new object[5];

            myState[0] = base.SaveViewState();
            myState[1] = (_currentNodeStyle != null) ? ((IStateManager)_currentNodeStyle).SaveViewState() : null; 
            myState[2] = (_nodeStyle != null) ? ((IStateManager)_nodeStyle).SaveViewState() : null;
            myState[3] = (_rootNodeStyle != null) ? ((IStateManager)_rootNodeStyle).SaveViewState() : null; 
            myState[4] = (_pathSeparatorStyle != null) ? ((IStateManager)_pathSeparatorStyle).SaveViewState() : null; 

            for (int i = 0; i 
        /// 
        ///    Marks the starting point to begin tracking and saving changes to the
        ///       control as part of the control viewstate.
        ///  
        protected override void TrackViewState() {
            base.TrackViewState(); 
 
            if (_currentNodeStyle != null)
                ((IStateManager)_currentNodeStyle).TrackViewState(); 

            if (_nodeStyle != null)
                ((IStateManager)_nodeStyle).TrackViewState();
 
            if (_rootNodeStyle != null)
                ((IStateManager)_rootNodeStyle).TrackViewState(); 
 
            if (_pathSeparatorStyle != null)
                ((IStateManager)_pathSeparatorStyle).TrackViewState(); 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI.WebControls { 
 
    using System;
    using System.Collections; 
    using System.ComponentModel;
    using System.Security.Permissions;
    using System.Web;
    using System.Web.UI; 
    using System.Web.Util;
 
 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    [
    Designer("System.Web.UI.Design.WebControls.SiteMapPathDesigner, " + AssemblyRef.SystemDesign)
    ]
 
    public class SiteMapPath : CompositeControl {
 
        private const string _defaultSeparator = " > "; 
        private const string _afterSiteMapPathMark = "_SkipLink";
 
        private static readonly object _eventItemCreated = new object();
        private static readonly object _eventItemDataBound = new object();
        private SiteMapProvider _provider = null;
 
        private Style _currentNodeStyle;
        private Style _rootNodeStyle; 
        private Style _nodeStyle; 
        private Style _pathSeparatorStyle;
 
        private Style _mergedCurrentNodeStyle;
        private Style _mergedRootNodeStyle;

        private ITemplate _currentNodeTemplate; 
        private ITemplate _rootNodeTemplate;
        private ITemplate _nodeTemplate; 
        private ITemplate _pathSeparatorTemplate; 

 
        public SiteMapPath() {
        }

 
        [
        DefaultValue(null), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty), 
        WebCategory("Styles"),
        WebSysDescription(SR.SiteMapPath_CurrentNodeStyle)
        ]
        public Style CurrentNodeStyle { 
            get {
                if (_currentNodeStyle == null) { 
                    _currentNodeStyle = new Style(); 
                    if (IsTrackingViewState) {
                        ((IStateManager)_currentNodeStyle).TrackViewState(); 
                    }
                }

                return _currentNodeStyle; 
            }
        } 
 

        ///  
        /// Gets or sets the  that defines how the current node is rendered. 
        /// 
        [
        Browsable(false), 
        DefaultValue(null),
        PersistenceMode(PersistenceMode.InnerProperty), 
        TemplateContainer(typeof(SiteMapNodeItem)), 
        WebSysDescription(SR.SiteMapPath_CurrentNodeTemplate)
        ] 
        public virtual ITemplate CurrentNodeTemplate {
            get {
                return _currentNodeTemplate;
            } 
            set {
                _currentNodeTemplate = value; 
            } 
        }
 

        [
        DefaultValue(null),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty), 
        WebCategory("Styles"), 
        WebSysDescription(SR.SiteMapPath_NodeStyle)
        ] 
        public Style NodeStyle {
            get {
                if (_nodeStyle == null) {
                    _nodeStyle = new Style(); 
                    if (IsTrackingViewState) {
                        ((IStateManager)_nodeStyle).TrackViewState(); 
                    } 
                }
 
                return _nodeStyle;
            }
        }
 

        ///  
        /// Gets or sets the  that defines how the parent node is rendered.  
        /// 
        [ 
        Browsable(false),
        DefaultValue(null),
        PersistenceMode(PersistenceMode.InnerProperty),
        TemplateContainer(typeof(SiteMapNodeItem)), 
        WebSysDescription(SR.SiteMapPath_NodeTemplate)
        ] 
        public virtual ITemplate NodeTemplate { 
            get {
                return _nodeTemplate; 
            }
            set {
                _nodeTemplate = value;
            } 
        }
 
 
        /// 
        ///    Indicates the number of parent nodes to display. 
        /// 
        [
        DefaultValue(-1),
        Themeable(false), 
        WebCategory("Behavior"),
        WebSysDescription(SR.SiteMapPath_ParentLevelsDisplayed) 
        ] 
        public virtual int ParentLevelsDisplayed {
            get{ 
                object o = ViewState["ParentLevelsDisplayed"];
                if (o == null) {
                    return -1;
                } 
                return (int)o;
            } 
            set { 
                if (value < -1) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["ParentLevelsDisplayed"] = value;
            }
        } 

 
        [ 
        DefaultValue(PathDirection.RootToCurrent),
        WebCategory("Appearance"), 
        WebSysDescription(SR.SiteMapPath_PathDirection)
        ]
        public virtual PathDirection PathDirection {
            get { 
                object o = ViewState["PathDirection"];
                if (o == null) { 
                    return PathDirection.RootToCurrent; 
                }
                return (PathDirection)o; 
            }
            set {
                if ((value < PathDirection.RootToCurrent) || (value > PathDirection.CurrentToRoot)) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
                ViewState["PathDirection"] = value; 
            } 
        }
 

        [
        DefaultValue(_defaultSeparator),
        Localizable(true), 
        WebCategory("Appearance"),
        WebSysDescription(SR.SiteMapPath_PathSeparator) 
        ] 
        public virtual string PathSeparator {
            get { 
                string s = (string)ViewState["PathSeparator"];
                if (s == null) {
                    return _defaultSeparator;
                } 
                return s;
            } 
            set { 
                ViewState["PathSeparator"] = value;
            } 
        }


        [ 
        DefaultValue(null),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true), 
        PersistenceMode(PersistenceMode.InnerProperty),
        WebCategory("Styles"), 
        WebSysDescription(SR.SiteMapPath_PathSeparatorStyle)
        ]
        public Style PathSeparatorStyle {
            get { 
                if (_pathSeparatorStyle == null) {
                    _pathSeparatorStyle = new Style(); 
                    if (IsTrackingViewState) { 
                        ((IStateManager)_pathSeparatorStyle).TrackViewState();
                    } 
                }

                return _pathSeparatorStyle;
            } 
        }
 
 
        /// 
        /// Gets or sets the  that defines how the path Separator is rendered.  
        /// 
        [
        Browsable(false),
        DefaultValue(null), 
        PersistenceMode(PersistenceMode.InnerProperty),
        TemplateContainer(typeof(SiteMapNodeItem)), 
        WebSysDescription(SR.SiteMapPath_PathSeparatorTemplate) 
        ]
        public virtual ITemplate PathSeparatorTemplate { 
            get {
                return _pathSeparatorTemplate;
            }
            set { 
                _pathSeparatorTemplate = value;
            } 
        } 

 
        [
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        WebSysDescription(SR.SiteMapPath_Provider) 
        ]
        public SiteMapProvider Provider { 
            get { 
                // Designer must specify a provider, as code below access runtime config
                if (_provider != null || DesignMode) 
                    return _provider;

                // If not specified, use the default provider.
                if (String.IsNullOrEmpty(SiteMapProvider)) { 
                    _provider = SiteMap.Provider;
 
                    if (_provider == null) { 
                        throw new HttpException(SR.GetString(SR.SiteMapDataSource_DefaultProviderNotFound));
                    } 
                }
                else {
                    _provider = SiteMap.Providers[SiteMapProvider];
 
                    if (_provider == null) {
                        throw new HttpException(SR.GetString(SR.SiteMapDataSource_ProviderNotFound, SiteMapProvider)); 
                    } 
                }
 
                return _provider;
            }
            set {
                _provider = value; 
            }
        } 
 

        [ 
        DefaultValue(false),
        WebCategory("Appearance"),
        WebSysDescription(SR.SiteMapPath_RenderCurrentNodeAsLink)
        ] 
        public virtual bool RenderCurrentNodeAsLink {
            get { 
                object o = ViewState["RenderCurrentNodeAsLink"]; 
                if (o == null) {
                    return false; 
                }

                return (bool)o;
            } 
            set {
                ViewState["RenderCurrentNodeAsLink"] = value; 
            } 
        }
 

        [
        DefaultValue(null),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
        NotifyParentProperty(true),
        PersistenceMode(PersistenceMode.InnerProperty), 
        WebCategory("Styles"), 
        WebSysDescription(SR.SiteMapPath_RootNodeStyle)
        ] 
        public Style RootNodeStyle {
            get {
                if (_rootNodeStyle == null) {
                    _rootNodeStyle = new Style(); 
                    if (IsTrackingViewState) {
                        ((IStateManager)_rootNodeStyle).TrackViewState(); 
                    } 
                }
 
                return _rootNodeStyle;
            }
        }
 

        ///  
        /// Gets or sets the  that defines how the root node is rendered.  
        /// 
        [ 
        Browsable(false),
        DefaultValue(null),
        PersistenceMode(PersistenceMode.InnerProperty),
        TemplateContainer(typeof(SiteMapNodeItem)), 
        WebSysDescription(SR.SiteMapPath_RootNodeTemplate)
        ] 
        public virtual ITemplate RootNodeTemplate { 
            get {
                return _rootNodeTemplate; 
            }
            set {
                _rootNodeTemplate = value;
            } 
        }
 
 
        [
        Localizable(true), 
        WebCategory("Accessibility"),
        WebSysDefaultValue(SR.SiteMapPath_Default_SkipToContentText),
        WebSysDescription(SR.SiteMapPath_SkipToContentText)
        ] 
        public virtual String SkipLinkText {
            get { 
                string s = ViewState["SkipLinkText"] as String; 
                return s == null ? SR.GetString(SR.SiteMapPath_Default_SkipToContentText) : s;
            } 
            set {
                ViewState["SkipLinkText"] = value;
            }
        } 

 
        [ 
        DefaultValue(true),
        Themeable(false), 
        WebCategory("Behavior"),
        WebSysDescription(SR.SiteMapPath_ShowToolTips)
        ]
        public virtual bool ShowToolTips { 
            get {
                object o = ViewState["ShowToolTips"]; 
                if (o == null) { 
                    return true;
                } 

                return (bool)o;
            }
            set { 
                ViewState["ShowToolTips"] = value;
            } 
        } 

 
        [
        DefaultValue(""),
        Themeable(false),
        WebCategory("Behavior"), 
        WebSysDescription(SR.SiteMapPath_SiteMapProvider)
        ] 
        public virtual string SiteMapProvider { 
            get {
                string provider = ViewState["SiteMapProvider"] as string; 
                return (provider == null) ? String.Empty : provider;
            }
            set {
                ViewState["SiteMapProvider"] = value; 
                _provider = null;
            } 
        } 

 
        [
        WebCategory("Action"),
        WebSysDescription(SR.DataControls_OnItemCreated)
        ] 
        public event SiteMapNodeItemEventHandler ItemCreated {
            add { 
                Events.AddHandler(_eventItemCreated, value); 
            }
            remove { 
                Events.RemoveHandler(_eventItemCreated, value);
            }
        }
 

        ///  
        /// Occurs when an item is databound within a  control tree. 
        /// 
        [ 
        WebCategory("Action"),
        WebSysDescription(SR.SiteMapPath_OnItemDataBound)
        ]
        public event SiteMapNodeItemEventHandler ItemDataBound { 
            add {
                Events.AddHandler(_eventItemDataBound, value); 
            } 
            remove {
                Events.RemoveHandler(_eventItemDataBound, value); 
            }
        }

 
        /// 
        ///  
        ///  
        protected internal override void CreateChildControls() {
            Controls.Clear(); 
            CreateControlHierarchy();
            ClearChildState();
        }
 

        ///  
        ///    A protected method. Creates a control hierarchy based on current sitemap OM. 
        /// 
        protected virtual void CreateControlHierarchy() { 
            if (Provider == null)
                return;

            int index = 0; 

            CreateMergedStyles(); 
 
            SiteMapNode currentNode = Provider.GetCurrentNodeAndHintAncestorNodes(-1);
            if (currentNode != null) { 
                SiteMapNode parentNode = currentNode.ParentNode;
                if (parentNode != null) {
                    CreateControlHierarchyRecursive(ref index, parentNode, ParentLevelsDisplayed);
                } 

                CreateItem(index++, SiteMapNodeItemType.Current, currentNode); 
            } 
        }
 
        private void CreateControlHierarchyRecursive(ref int index, SiteMapNode node, int parentLevels) {
            if (parentLevels == 0)
                return;
 
            SiteMapNode parentNode = node.ParentNode;
            if (parentNode != null) { 
                CreateControlHierarchyRecursive(ref index, parentNode, parentLevels - 1); 
                CreateItem(index++, SiteMapNodeItemType.Parent, node);
            } 
            else {
                CreateItem(index++, SiteMapNodeItemType.Root, node);
            }
 
            CreateItem(index, SiteMapNodeItemType.PathSeparator , null);
        } 
 
        private SiteMapNodeItem CreateItem(int itemIndex, SiteMapNodeItemType itemType, SiteMapNode node) {
            SiteMapNodeItem item = new SiteMapNodeItem(itemIndex, itemType); 

            int index = (PathDirection == PathDirection.CurrentToRoot? 0 : -1);

            SiteMapNodeItemEventArgs e = new SiteMapNodeItemEventArgs(item); 

            //Add sitemap nodes so that they are accessible during events. 
            item.SiteMapNode = node; 
            InitializeItem(item);
 
            // Notify items
            OnItemCreated(e);

            // Add items based on PathDirection. 
            Controls.AddAt(index, item);
 
            // Databind. 
            item.DataBind();
 
            // Notify items.
            OnItemDataBound(e);

            item.SiteMapNode = null; 

            // SiteMapNodeItem is dynamically created each time, don't track viewstate. 
            item.EnableViewState = false; 

            return item; 
        }

        private void CopyStyle(Style toStyle, Style fromStyle) {
            Debug.Assert(toStyle != null); 

            // Review: How to change the default value of Font.Underline? 
            if (fromStyle != null && fromStyle.IsSet(System.Web.UI.WebControls.Style.PROP_FONT_UNDERLINE)) 
                toStyle.Font.Underline = fromStyle.Font.Underline;
 
            toStyle.CopyFrom(fromStyle);
        }

        private void CreateMergedStyles() { 
            _mergedCurrentNodeStyle = new Style();
            CopyStyle(_mergedCurrentNodeStyle, _nodeStyle); 
            CopyStyle(_mergedCurrentNodeStyle, _currentNodeStyle); 

            _mergedRootNodeStyle = new Style(); 
            CopyStyle(_mergedRootNodeStyle, _nodeStyle);
            CopyStyle(_mergedRootNodeStyle, _rootNodeStyle);
        }
 

        ///  
        ///  
        /// Overriden to handle our own databinding.
        ///  
        public override void DataBind() {
            // do our own databinding
            OnDataBinding(EventArgs.Empty);
 
            // contained items will be databound after they have been created,
            // so we don't want to walk the hierarchy here. 
        } 

 
        /// 
        /// A protected method. Populates iteratively the specified  with a
        ///    sub-hierarchy of child controls.
        ///  
        protected virtual void InitializeItem(SiteMapNodeItem item) {
            Debug.Assert(_mergedCurrentNodeStyle != null && _mergedRootNodeStyle != null); 
 
            ITemplate template = null;
            Style style = null; 
            SiteMapNodeItemType itemType = item.ItemType;
            SiteMapNode node = item.SiteMapNode;

            switch (itemType) { 
                case SiteMapNodeItemType.Root :
                    template = RootNodeTemplate != null? RootNodeTemplate : NodeTemplate; 
                    style = _mergedRootNodeStyle; 
                    break;
 
                case SiteMapNodeItemType.Parent :
                    template = NodeTemplate;
                    style = _nodeStyle;
                    break; 

                case SiteMapNodeItemType.Current : 
                    template = CurrentNodeTemplate != null? CurrentNodeTemplate : NodeTemplate; 
                    style = _mergedCurrentNodeStyle;
                    break; 

                case SiteMapNodeItemType.PathSeparator :
                    template = PathSeparatorTemplate;
                    style = _pathSeparatorStyle; 
                    break;
            } 
 
            if (template == null) {
                if (itemType == SiteMapNodeItemType.PathSeparator) { 
                    Literal separatorLiteral = new Literal();
                    separatorLiteral.Mode = LiteralMode.Encode;
                    separatorLiteral.Text = PathSeparator;
                    item.Controls.Add(separatorLiteral); 
                    item.ApplyStyle(style);
                } 
                else if (itemType == SiteMapNodeItemType.Current && !RenderCurrentNodeAsLink) { 
                    Literal currentNodeLiteral = new Literal();
                    currentNodeLiteral.Mode = LiteralMode.Encode; 
                    currentNodeLiteral.Text = node.Title;
                    item.Controls.Add(currentNodeLiteral);
                    item.ApplyStyle(style);
                } 
                else {
                    HyperLink link = new HyperLink(); 
 
                    if (style != null && style.IsSet(System.Web.UI.WebControls.Style.PROP_FONT_UNDERLINE))
                        link.Font.Underline = style.Font.Underline; 

                    link.EnableTheming = false;
                    link.Enabled = this.Enabled;
                    // VSWhidbey 281869 Don't modify input when url pointing to unc share 
                    if (node.Url.StartsWith("\\\\", StringComparison.Ordinal)) {
                        link.NavigateUrl = ResolveClientUrl(HttpUtility.UrlPathEncode(node.Url)); 
                    } 
                    else {
                        link.NavigateUrl = Context != null? 
                            Context.Response.ApplyAppPathModifier(ResolveClientUrl(HttpUtility.UrlPathEncode(node.Url))) : node.Url;
                    }
                    link.Text = HttpUtility.HtmlEncode(node.Title);
                    if (ShowToolTips) 
                        link.ToolTip = node.Description;
                    item.Controls.Add(link); 
                    link.ApplyStyle(style); 
                }
            } 
            else {
                template.InstantiateIn(item);
                item.ApplyStyle(style);
            } 
        }
 
 
        /// 
        ///  
        /// Loads a saved state of the . 
        /// 
        protected override void LoadViewState(object savedState) {
            if (savedState != null) { 
                object[] myState = (object[])savedState;
 
                Debug.Assert(myState.Length == 5); 

                base.LoadViewState(myState[0]); 

                if (myState[1] != null)
                    ((IStateManager)CurrentNodeStyle).LoadViewState(myState[1]);
 
                if (myState[2] != null)
                    ((IStateManager)NodeStyle).LoadViewState(myState[2]); 
 
                if (myState[3] != null)
                    ((IStateManager)RootNodeStyle).LoadViewState(myState[3]); 

                if (myState[4] != null)
                    ((IStateManager)PathSeparatorStyle).LoadViewState(myState[4]);
            } 
            else {
                base.LoadViewState(null); 
            } 
        }
 

        /// 
        /// 
        /// A protected method. Raises the  event. 
        /// 
        protected override void OnDataBinding(EventArgs e) { 
            base.OnDataBinding(e); 

            // reset the control state 
            Controls.Clear();
            ClearChildState();

            CreateControlHierarchy(); 
            ChildControlsCreated = true;
        } 
 

        ///  
        /// A protected method. Raises the  event.
        /// 
        protected virtual void OnItemCreated(SiteMapNodeItemEventArgs e) {
            SiteMapNodeItemEventHandler onItemCreatedHandler = 
                (SiteMapNodeItemEventHandler)Events[_eventItemCreated];
            if (onItemCreatedHandler != null) { 
                onItemCreatedHandler(this, e); 
            }
        } 


        /// 
        /// A protected method. Raises the  
        /// event.
        ///  
        protected virtual void OnItemDataBound(SiteMapNodeItemEventArgs e) { 
            SiteMapNodeItemEventHandler onItemDataBoundHandler =
                (SiteMapNodeItemEventHandler)Events[_eventItemDataBound]; 
            if (onItemDataBoundHandler != null) {
                onItemDataBoundHandler(this, e);
            }
        } 

 
        ///  
        /// 
        protected internal override void Render(HtmlTextWriter writer) { 
            // Copied from CompositeControl.cs
            if (DesignMode) {
                ChildControlsCreated = false;
                EnsureChildControls(); 
            }
 
            base.Render(writer); 
        }
 

        /// 
        ///     Adds the SkipToContextText.
        ///  

        protected internal override void RenderContents(HtmlTextWriter writer) { 
            // Only render the accessibility link at runtime. 
            bool accessibilityMode = !String.IsNullOrEmpty(SkipLinkText) && !DesignMode;
 
            String href = ClientID + _afterSiteMapPathMark;

            if (accessibilityMode) {
                //  
                writer.AddAttribute(HtmlTextWriterAttribute.Href, "#" + href);
                writer.RenderBeginTag(HtmlTextWriterTag.A); 
 
                // skipToContentText
                writer.AddAttribute(HtmlTextWriterAttribute.Alt, SkipLinkText); 
                writer.AddAttribute(HtmlTextWriterAttribute.Height, "0");
                writer.AddAttribute(HtmlTextWriterAttribute.Width, "0");
                writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "0px");
                writer.AddAttribute(HtmlTextWriterAttribute.Src, SpacerImageUrl); 
                writer.RenderBeginTag(HtmlTextWriterTag.Img);
                writer.RenderEndTag(); 
 
                // 
                writer.RenderEndTag(); 
            }

            base.RenderContents(writer);
 
            if (accessibilityMode) {
                //  
                writer.AddAttribute(HtmlTextWriterAttribute.Id, href); // XHTML 1.1 needs id instead of name 
                writer.RenderBeginTag(HtmlTextWriterTag.A);
                writer.RenderEndTag(); 
            }
        }

 
        /// 
        ///  
        /// Stores the state of the System.Web.UI.WebControls.SiteMapPath. 
        /// 
        protected override object SaveViewState() { 
            object[] myState = new object[5];

            myState[0] = base.SaveViewState();
            myState[1] = (_currentNodeStyle != null) ? ((IStateManager)_currentNodeStyle).SaveViewState() : null; 
            myState[2] = (_nodeStyle != null) ? ((IStateManager)_nodeStyle).SaveViewState() : null;
            myState[3] = (_rootNodeStyle != null) ? ((IStateManager)_rootNodeStyle).SaveViewState() : null; 
            myState[4] = (_pathSeparatorStyle != null) ? ((IStateManager)_pathSeparatorStyle).SaveViewState() : null; 

            for (int i = 0; i 
        /// 
        ///    Marks the starting point to begin tracking and saving changes to the
        ///       control as part of the control viewstate.
        ///  
        protected override void TrackViewState() {
            base.TrackViewState(); 
 
            if (_currentNodeStyle != null)
                ((IStateManager)_currentNodeStyle).TrackViewState(); 

            if (_nodeStyle != null)
                ((IStateManager)_nodeStyle).TrackViewState();
 
            if (_rootNodeStyle != null)
                ((IStateManager)_rootNodeStyle).TrackViewState(); 
 
            if (_pathSeparatorStyle != null)
                ((IStateManager)_pathSeparatorStyle).TrackViewState(); 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK