博客地址 http://blog.csdn.net/foxdave

本篇描述自定义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
}
}

大致的功能就完成了,下一讲叙述如何在母版页应用这个菜单声明。

SharePoint开发 - 自定义导航菜单(一)菜单声明与配置的更多相关文章

  1. SharePoint开发 - 自定义导航菜单(二)母版页的菜单应用

    博客地址 http://blog.csdn.net/foxdave 接上篇点击打开链接 本篇叙述在母版页中应用之前的配置信息生成菜单,主要涉及到母版页的自定义,并应用了第三方控件库DevExpress ...

  2. SharePoint开发 - 自定义导航菜单(三)附其他代码

    博客地址 http://blog.csdn.net/foxdave 接上篇点击打开链接 LeftNavGroupTemplate.cs internal class LeftNavGroupTempl ...

  3. SharePoint开发 - 自定义页面(错误页、登出页)

    博客地址 http://blog.csdn.net/foxdave 本文叙述如何自定义SharePoint的固有页面,比较简单,用一句话说就是"做个页面,写一句代码." 创建Sha ...

  4. 步步为营 SharePoint 开发学习笔记系列总结

    转:http://www.cnblogs.com/springyangwc/archive/2011/08/03/2126763.html 概要 为时20多天的sharepoint开发学习笔记系列终于 ...

  5. 为SharePoint网站创建自定义导航菜单

    转:http://kaneboy.blog.51cto.com/1308893/397779 相信不少人都希望把SharePoint网站内置的那个顶部导航菜单,换成自己希望的样式.由于SharePoi ...

  6. SharePoint 2013 自定义扩展菜单

    在对SharePoint进行开发或者功能扩展的时候,经常需要对一些默认的菜单进行扩展,以使我们开发的东西更适合SharePoint本身的样式.SharePoint的各种功能菜单,像网站设置.Ribbo ...

  7. 每日学习心得:SharePoint 2013 自定义列表项添加Callout菜单项、文档关注、SharePoint服务端对象模型查询

    前言: 前一段时间一直都比较忙,没有什么时间进行总结,刚好节前项目上线,同时趁着放假可以好好的对之前遇到的一些问题进行总结.主要内容有使用SharePoint服务端对象模型进行查询.为SharePoi ...

  8. SharePoint 2013 自定义扩展菜单(二)

    接博文<SharePoint 2013 自定义扩展菜单>,多加了几个例子,方便大家理解. 例七 列表设置菜单扩展(listedit.aspx) 扩展效果 XML描述 <CustomA ...

  9. 第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单

    我们来了解一下 自定义菜单创建接口: http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_to ...

随机推荐

  1. nginx日志分析手机使用频次

    __author__ = 'similarface' from collections import defaultdict import glob ip = r"?P<ip>[ ...

  2. entity reference在views中的运用

    一个views block可以获取从url过来的nid,某个node的有entity reference字段, 填入一点数据,然后在views里关联一下这个entity reference field ...

  3. 关于MySQL大牛周振兴的博客

    博客内容比较丰富 MySQL管理 数据恢复 linux TCP 个人生活感触 不过内容总体是笔记式的,更适合自己看,不适合初学者去follow.不过对MySQL比较熟悉的人,可以看看,作为扩展眼界的途 ...

  4. 为什么要使用SLF4J而不是Log4J

      每一个Java程序员都知道日志对于任何一个Java应用程序,尤其是服务端程序是至关重要的,而很多程序员也已经熟悉各种不同的日志库如java.util.logging.Apache log4j.lo ...

  5. PHP框架学习错误总结

    错误一: Fatal error: “Uncaught exception 'Zend_Controller_Response_Exception' with message 'Cannot send ...

  6. hdu 1598 find the most comfortable road(枚举+卡鲁斯卡尔最小生成树)

    find the most comfortable road Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  7. easyui $.parser.parse 页面重新渲染

    一些dom元素是动态拼接上的easui的样式,由于页面已经渲染过了,所以需要手动执行渲染某个部件或者整个页面 $.parser.parse(); // parse all the page $.par ...

  8. DataOdinalRegression

    clear name={'SCV1V1','SVC1VA','SVR','CSSVC','SVMOP','NNOP','ELMOP','GPOR','KDLOR','POM',... 'NNPOM', ...

  9. 串口调试,提示the given port name does not start with COM/com异常解决办法,,发现是打印机在搞怪

    串口测试时,用到串口,把打印机的拔下来,换上测试的,程序一打开就提示错误:the given port name does not start with COM/com or does not res ...

  10. struts2视频学习笔记 13-14(自定义局部和全局类型转换器(转换Date格式))

    课时13 自定义类型转换器 局部(对某个action类) package tutorial; import java.util.Date; public class HelloWorld { priv ...