本篇描述自定义sharepoint菜单的一种方式,自定义菜单适用于一些门户等需求的网站
自定义的菜单有自己的数据源,可以是数据表,可以是XML,本篇叙述的是采用XML数据源作为菜单的声明定义部分,将XML以文件的格式保存到网站中自己创建的配置文档库中
XML菜单的格式形如下面的格式,其中有菜单标题title属性,有菜单所属的权限用户组SPGroups属性,有菜单的链接url属性,实际应用中可以添加更多的字段。
<SiteMap> <SiteMapNode title="我的项目" SPGroups="质量技术中心;造价中心;分公司;第3分公司;工程部;资金中心;核算中心;运营中心;内审中心;财务中心;核算中心;测试组;资金组" > <SiteMapNode title="项目管理" url="/_layouts/SP_MIP/PI/PI_BasicInfoSearchInfo.aspx" SPGroups="质量技术中心;资金中心;核算中心;造价中心;财务中心;分公司;第3分公司;工程部;运营中心;内审中心;核算中心;测试组;资金组"/> </SiteMapNode> </SiteMap>
我们要给网站管理员提供一个接口来定义导航菜单,比如放到网站设置里,如图所示
新建一个SharePoint解决方案,添加一个元素Element用来定义这个网站设置菜单(CustomActionGroup和CustomAction节点)。代码如下(这里包含我后期添加的一个用户修改密码的功能,这里不做说明)
<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <CustomActionGroup Id="SPMIPNavigation" Title="SPMIP导航" Description = "SPMIP导航" Location = "Microsoft.SharePoint.SiteSettings" Sequence = "1999" ImageUrl="/_layouts/Images/SiteSettings_SPMIPNavigation_48x48.png"> </CustomActionGroup> <CustomAction Id="SPMIPTopNav" GroupId="SPMIPNavigation" Location="Microsoft.SharePoint.SiteSettings" Rights="ManageWeb" Sequence="2000" Title="顶部导航" Description="顶部导航"> <UrlAction Url="{SiteUrl}/_layouts/SP_MIP/TopNav.aspx" /> </CustomAction> <CustomAction Id="SPMIPLeftNav" GroupId="SPMIPNavigation" Location="Microsoft.SharePoint.SiteSettings" Rights="ManageWeb" Sequence="2010" Title="左侧导航" Description="左侧导航"> <UrlAction Url="{SiteUrl}/_layouts/SP_MIP/LeftNav.aspx" /> </CustomAction> <CustomAction Id="SPMIPChangePassword" GroupId="PersonalActions" Location="Microsoft.SharePoint.StandardMenu" Sequence="1000" Title="修改密码" Description="修改密码" ImageUrl="{SiteUrl}/_layouts/images/Welcome_SPMIPChangePwd_32x32.png"> <UrlAction Url="javascript:Show();"/> </CustomAction> </Elements>
添加相应的网站资产,如设置图片。添加两个页面TopNav.aspx和LeftNav.aspx。两个页面其实没什么区别,以TopNav为例,添加一个多行文本框,一个保存按钮就可以了。
核心页面代码
<table border="0" width="100%" cellspacing="0" cellpadding="0"> <wssuc:InputFormSection ID="InputFormSection" Title="顶部导航" runat="server" Description="顶部导航"> <Template_InputFormControls> <wssuc:InputFormControl ID="InputFormControl" runat="server"> <Template_Control> <table border="0" cellpadding="0" cellspacing="0"> <tr> <td align="right" style="padding-bottom: 5px"> <a href="javascript:topnav_showFullScreen('<%= txtNavXml.ClientID %>', '<%= txtNavXmlPop.ClientID %>');" style="color: #0072bc;"> <asp:Literal ID="ltl" runat="server" Text="全屏编辑" /> </a> </td> </tr> <tr> <td> <asp:TextBox ID="txtNavXml" runat="server" Wrap="false" TextMode="MultiLine" Rows="22" Width="600px" /> </td> </tr> </table> </Template_Control> </wssuc:InputFormControl> </Template_InputFormControls> </wssuc:InputFormSection> <wssuc:ButtonSection ID="bts" runat="server" ShowStandardCancelButton="false"> <Template_Buttons> <asp:Button runat="server" class="ms-ButtonHeightWidth" Text="保存" ID="btnSave" OnClick="btnSave_OnClick" /> <asp:Button runat="server" class="ms-ButtonHeightWidth" Text="取消" ID="btnClose" OnClientClick="TopNav_Close_Click(); return false;" /> </Template_Buttons> </wssuc:ButtonSection> </table> <table id="tblFullScreen" border="0" cellpadding="0" cellspacing="0" class="tblPop"> <tr> <td align="center" valign="top"> <table border="0" cellpadding="5" cellspacing="0" width="100%"> <tr> <td> <asp:TextBox ID="txtNavXmlPop" runat="server" Wrap="false" TextMode="MultiLine" Rows="28" Width="99%" /> </td> </tr> <tr> <td align="center"> <a href="javascript:topnav_hideFullScreen('<%= txtNavXml.ClientID %>', '<%= txtNavXmlPop.ClientID %>');" style="color: #0072bc;"> <asp:Literal ID="ltlClose" runat="server" Text="关闭" /> </a> </td> </tr> </table> </td> </tr> </table>
按钮后台的处理事件要做的事情就是把XML配置文件的内容读取出来,并把用户更改的XML定义保存回文档库的XML文件中。
protected void btnSave_OnClick(object sender, EventArgs e) { try { Config.Save(base.Web, this.txtNavXml.Text, Config.NavType.Top); SPUtility.Redirect("settings.aspx", SPRedirectFlags.RelativeToLayoutsPage, HttpContext.Current); } catch (Exception exception) { SPMIPTrace.WriteError("SPMIPNavigation", exception); } } protected void Page_Load(object sender, EventArgs e) { if (!base.IsPostBack) { this.txtNavXml.Text = Config.Load(base.Web, Config.NavType.Top); } }
class Config { public static string Load(SPWeb web, NavType navType) { string str = null; try { StreamReader reader; SPList settingList = SPMIPUtility.CheckSettingList("SPMIPSetting"); switch (navType) { case NavType.Top: { SPFile topNavSettingFile = settingList.RootFolder.Files["TopNav.xml"]; if (topNavSettingFile.Exists) { using (reader = new StreamReader(topNavSettingFile.OpenBinaryStream())) { str = reader.ReadToEnd(); } } break; } case NavType.Left: { SPFile leftNavSettingFile = settingList.RootFolder.Files["LeftNav.xml"]; if (leftNavSettingFile.Exists) { using (reader = new StreamReader(leftNavSettingFile.OpenBinaryStream())) { str = reader.ReadToEnd(); } } break; } } return str; } catch (Exception exception) { SPMIPTrace.WriteError("SPMIPNavigation", exception); return str; } } public static bool Save(SPWeb web, string fileContent, NavType navType) { bool flag = false; try { SPList settingList = SPMIPUtility.CheckSettingList("SPMIPSetting"); byte[] bytes = Encoding.UTF8.GetBytes(fileContent); web.AllowUnsafeUpdates = true; switch (navType) { case NavType.Top: settingList.RootFolder.Files.Add("TopNav.xml", bytes, true); break; case NavType.Left: settingList.RootFolder.Files.Add("LeftNav.xml", bytes, true); break; } flag = true; } catch (Exception exception) { SPMIPTrace.WriteError("SPMIPNavigation", exception); } return flag; } public enum NavType { Top, Left } }
大致的功能就完成了,下一讲叙述如何在母版页应用这个菜单声明。
时间: 2024-11-07 16:56:14