65.9K
CodeProject 正在变化。 阅读更多。
Home

如何在 SharePoint 2010 中创建自定义顶部和左侧导航

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2014年12月2日

CPOL

5分钟阅读

viewsIcon

20208

downloadIcon

143

如何在 SharePoint 2010 中创建自定义顶部和左侧导航

引言

每个 SharePoint 版本都带有开箱即用的导航功能,这非常有用。您可以快速创建站点导航,提供一些受众,然后就可以设置站点的导航了。

假设您有一些非常奇怪的业务需求,即开箱即用的导航无法满足目的,并且被要求根据业务需求进行自定义,这对一些人来说将是一个挑战。

在我参与的一个项目中,有一个非常复杂的需求。我们需要根据某种模拟功能来操作顶部和左侧导航。例如,当用户 A 登录时,该用户将能够模拟另一个用户帐户。整个顶部和左侧导航的行为将就像实际被用户 A 模拟的用户已登录一样。

用户 A 登录后,会出现以下屏幕,他们可以从中单击帐户并模拟该帐户正在登录门户。

模拟后,自定义代码将生效,并加载以下导航。根据上面 Gridview 中单击了哪个帐户,两者都是不同的。而且,每个菜单下的子项也会因单击了哪个项而不同。

我们尝试通过受众和组来操作开箱即用的导航来实现这一点,但这并未达到预期的结果,并且报告了很多错误。普通用户的开箱即用导航会正常工作,但模拟的导航则不行。

实现此复杂业务需求的唯一可能解决方案是完全从头开始编写顶部和左侧导航,并根据业务需求进行编码。

那么,我们开始吧!

Sharepoint 内容类型和列表

构建自定义站点导航的第一步是拥有一个导航数据源。我们可以为此选择不同的选项。我选择了 SharePoint 自定义列表。选择自定义列表的原因很简单。我们的业务需求是有一个父导航和它下面的子项,只有一级。

内容类型

创建以下内容类型

  • 文件夹内容类型,用于创建表示父导航项的文件夹

    名称 类型 状态 来源
    Nav Item URL 超链接或图片 可选 自定义导航文件夹
    Nav Link Item Audience 人员或组 可选 自定义导航文件夹
    Nav Link Item Order 数字 必需 自定义导航文件夹
    Nav Link Item Open New window 选择 可选 自定义导航文件夹
    标题 单行文本 隐藏 项目
  • 项目内容类型,用于创建表示子导航项的子项

    标题 单行文本 必需 项目
    Nav Item URL 超链接或图片 可选 自定义导航项
    Nav Link Item Audience 人员或组 可选 自定义导航项
    Nav Link Item Open New window 选择 可选 自定义导航项
    Nav Link Item Order 数字 必需 自定义导航项

SharePoint LIST

基于以上内容类型创建 SharePoint 列表并添加数据。

顶部导航由文件夹内容类型表示。

子项使用项目内容类型创建。

创建项的示例

Using the Code

创建本文档的全部目的是创建一个简单的项目,演示如何基于上述自定义列表创建 SharePoint 自定义导航。我不会深入探讨我如何实现业务需求的具体细节,但我会展示如何创建自定义导航,一旦您了解了基础知识,就可以修改代码以实现期望的结果。

  1. 第一步是创建一个接口来表示导航节点。相同的接口将用于表示顶部和左侧导航项。
    public interface INavigationItem
        {
            #region PROPERTIES
            /// <summary>
            ///
            /// </summary>
            string Title { get; set; }
            /// <summary>
            ///
            /// </summary>
            string Url { get; set; }
            /// <summary>
            ///
            /// </summary>
            string Audience { get; set; }
            /// <summary>
            ///
            /// </summary>
            int Order { get; set; }
            /// <summary>
            ///
            /// </summary>
            int Id { get; set; }
            /// <summary>
            ///
            /// </summary>
            bool IsOpenInNewWindow { get; set; }
            #endregion
            #region METHODS
            /// <summary>
            /// Get the parent navigation Items
            /// </summary>
            /// <param name="_TopNavList"></param>
            /// <param name="_Folder"></param>
            Dictionary<INavigationItem, int> 
            GetParentNavItems(SPList _TopNavList, SPFolder _Folder);
            /// <summary>
            /// Get the parent navigation Items
            /// </summary>
            /// <param name="sParentNavTitle"></param>
            /// <returns></returns>
            INavigationItem GetParentNavItem(string sParentNavTitle);
            /// <summary>
            /// Get child navigation Items
            /// </summary>
            /// <param name="_TopNavList"></param>
            /// <param name="_Folder"></param>
            /// <param name="iParentFolderID"></param>
            Dictionary<INavigationItem, int> GetChildNavItems
            (SPList _TopNavList, SPFolder _Folder, int iParentFolderID);
            /// <summary>
            /// Get child navigation Items
            /// </summary>
            /// <param name="_TopNavList"></param>
            /// <param name="_Folder"></param>
            /// <param name="iParentFolderID"></param>
            Dictionary<INavigationItem, int> 
            GetChildNavItems(SPList _TopNavList, SPFolder _Folder);
            /// <summary>
            /// Populate the navigation items
            /// </summary>
            /// <param name="_TopNavList"></param>
            /// <param name="_StartingFolder"></param>
            /// <param name="psmNode"></param>
            SiteMapNodeCollection PopluateNavigationItems
            (SPList _TopNavList, SPFolder _StartingFolder, PortalSiteMapNode psmNode);
            #endregion
        }
  2. 将创建一个 SharePoint 解决方案来编码导航解决方案。Sharepoint PortalSiteMapProvider 是用于表示节点的类。此类继承自 Sitemapnode 类。SiteMapNodePortalSiteMapNode 之间的区别在于 PortalSiteMapNode 使用 MOSS 安全修剪。这很好。请使用它。但是,Sharepoint 中没有 PortalSiteMapNodeCollection 类。您仍然使用 SiteMapNodeCollection 来添加和删除节点。
    public class TopNavigationProvider : PortalSiteMapProvider
    {
    
    }
    
    public class LeftNavigationProvider : PortalSiteMapProvider
    {
    
    }

    PortalSiteMapnode 类的 GetChildNodes 方法是创建节点的 方法。此方法有各种重写签名,可根据需要使用。我正在使用以下方法,节点对象将被装箱到 PortalSiteMapNode 以获取 SharePoint 节点。

      /// <summary>
      ///
     /// </summary>
    private SiteMapNodeCollection GetChildNodes(SiteMapNode node)
    {
       PortalSiteMapNode pNode = node as PortalSiteMapNode;
       //……………………………………
    }
  3. 然后将使用另一个类来设置整个导航(顶部和左侧),该类将继承自我们的接口以设置顶部和左侧导航。这些类将在提供程序类 GetChildNodes 方法中使用以创建导航。
     /// <summary>
        /// This class represents an Navigation Item
        /// </summary>
        public class TopNavigationItem : INavigationItem
        {
        }
    
     /// <summary>
        /// This class represents an Navigation Item
        /// </summary>
        public class LeftNavigationItem : INavigationItem
        {
        }
  4. 下一步是设置 Web.config。在 Web.config 的 sitemap 部分添加以下键。此处,TopNavigationProvider 是具有顶部导航逻辑的类的名称。
    <siteMap defaultProvider="CurrentNavigation" enabled="true">
          <providers>
            <add name="TopNavigationProvider" type="XYZ.Navigation.TopNavigationProvider,
            XYZ.Navigation, Version=1.0.0.0, Culture=neutral,
            PublicKeyToken=a1a91a3" NavigationType="Global" />
            <add name="LeftNavigationProvider" type="XYZ.Navigation.LeftNavigationProvider,
            XYZ.Navigation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a1a91a32d"
            NavigationType="Global" />
  5. 下一步是设置母版页。在站点母版页内,有两个部分代表顶部导航和左侧导航提供程序。我们将覆盖开箱即用的提供程序,并使用我们的自定义提供程序。直接修改母版页从来不是明智的做法。因此,请使用 SharePoint Designer 进行所有更改。编辑您的站点正在使用的母版页,并替换以下部分以使用我们的自定义提供程序。将母版页中的 <asp:ContentPlaceHolder id="PlaceHolderTopNavBar" runat="server"> 替换为以下内容以用于顶部导航栏。请使用您的 web.config 条目中顶部导航的准确 SiteMapProvider 名称。
    <asp:ContentPlaceHolder id="PlaceHolderTopNavBar" runat="server">
                                <h2 class="ms-hidden">
                                <SharePoint:EncodedLiteral runat="server"
                                text="<%$Resources:wss,topnav_pagetitle%>"
                                EncodeMethod="HtmlEncode"/></h2>
                                        <asp:ContentPlaceHolder id="PlaceHolderHorizontalNav"
                                        runat="server">
                                    <SharePoint:AspMenu
                                      ID="TopNavigationMenuV4"
                                      Runat="server"
                                      EnableViewState="true"
                                      DataSourceID="topSiteMap"
                                      AccessKey="<%$Resources:wss,navigation_accesskey%>"
                                      UseSimpleRendering="true"
                                      UseSeparateCss="false"
                                      Orientation="Horizontal"
                                      StaticDisplayLevels="1"
                                      MaximumDynamicDisplayLevels="3"
                                      SkipLinkText=""
                                      CssClass="s4-tn"/>
                                        <asp:SiteMapDataSource
                                                      SiteMapProvider="TopNavigationProvider"
                                                      StartFromCurrentNode="true"
                                                      StartingNodeOffset="0"
                                                      ShowStartingNode="false"
                                                      EnableViewState="true"
                                                      id="topSiteMap"
                                                      runat="server"
                                                  />
                                        </asp:ContentPlaceHolder>
                                </asp:ContentPlaceHolder>
  6. 将母版页中的 <asp:ContentPlaceHolder id="PlaceHolderLeftNavBar" runat="server"> 替换为以下内容以用于左侧导航栏。请使用您的 web.config 条目中左侧导航的准确 SiteMapProvider 名称。
    <asp:ContentPlaceHolder id="PlaceHolderLeftNavBar" runat="server">
                                <SharePoint:AspMenu
                                ID="CurrentNav"
                                EncodeTitle="false"
                                runat="server"
                                EnableViewState="false"
                                DataSourceID="ContentSiteMap"
                                UseSeparateCSS="false"
                                UseSimpleRendering="true"
                                Orientation="Vertical"
                                StaticDisplayLevels="2"
                                MaximumDynamicDisplayLevels="0"
                                CssClass="s4-ql"
                                SkipLinkText="<%$Resources:cms,masterpages_skiplinktext%>"/>
                                <asp:SiteMapDataSource
                                    SiteMapProvider="LeftNavigationProvider"
                                    ShowStartingNode="False"
                                    id="ContentSiteMap"
                                    runat="server"
                                    />
                        </asp:ContentPlaceHolder>
  7. 上传母版页并部署 WSP,您应该能够从 SharePoint 列表驱动自定义导航。

结论

因此,我们通过以上一些步骤了解了如何覆盖开箱即用的导航。随附了代码,您可以下载并创建一个基本解决方案来设置自定义导航。希望这对您有所帮助。

© . All rights reserved.