博客地址 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. JSON字符串如何转化成对象?

    解析 1.定义:是指将符合 JSON 语法规则的字符串转换成对象的过程. 2.不同的编程语言都提供了解析 JSON 字符串的方法,在这里主要讲解 JavaScript 中的解析方法.主要有三种: 1) ...

  2. CRLF CSRF XSS

    http://baike.baidu.com/link?url=BXWN2I6J23thrrm6JoEnAYvmNqp83llyaydaj5RYkq--tuJKSFuMuDMIoTPnKjthRUm3 ...

  3. phalcon: Profiling分析 profilter / Plugin结合,dispatcher调度控制器 监听sql执行日志

    个人觉得profilter 跟 logger 功能差不多,logger的功能在于写入,profilter功能在于sql后及时显示分析.都是对sql执行的的分析:一个是写入log文件,一个是直接在页面展 ...

  4. Weka 3: Data Mining Software in Java

    官方网站: Weka 3: Data Mining Software in Java 相关使用方法博客 WEKA使用教程(经典教程转载) (实例数据:bank-data.csv) Weka初步一.二. ...

  5. 联想手机#P1来了#P1背后的故事系列

    http://bbs.lenovo.com/forum.php?mod=viewthread&fid=928&tid=560992&extra=page%3D1 联想手机#P1 ...

  6. DSP28377S - ADC学习编程笔记

    DSP28377S -  ADC学习编程笔记 彭会锋 2016-08-04  20:19:52 1 ADC类型导致的配置区别 F28377S的ADC类型是Type 4类型,我的理解是不同类型的ADC采 ...

  7. java synchronized静态同步方法与非静态同步方法,同步语句块

    摘自:http://topmanopensource.iteye.com/blog/1738178 进行多线程编程,同步控制是非常重要的,而同步控制就涉及到了锁. 对代码进行同步控制我们可以选择同步方 ...

  8. Reverse Nodes in k-Group [LeetCode]

    Problem Description: http://oj.leetcode.com/problems/reverse-nodes-in-k-group/ Basic Idea: Do it lik ...

  9. 148. Sort List -- 时间复杂度O(n log n)

    Sort a linked list in O(n log n) time using constant space complexity. 归并排序 struct ListNode { int va ...

  10. inout

    在函数声明时就用inout代替var  这样以后可以在函数内部修改外面的值 类似于C语言的传入指针 func change (inout num:Int) { num = 10 } var a = 2 ...