2010年1月18日,星期一

定制功能区(part 1) –创建选项卡,组和控件

[此帖子于2011年9月更新,其中包含修复程序和更多信息–详见文字]

在本系列文章中:

  1. 定制功能区–创建选项卡,组和控件 (this post)
  2. 将功能区项目添加到现有选项卡/组中
  3. 功能区自定义-下拉控件,客户端对象模型和JavaScript页面组件
  4. 通过Web部件和现场控件以编程方式自定义功能区
  5. ** 2011年10月-下载本系列(以及更多)中的代码示例** 

现在,一些不错的帖子开始出现在SharePoint 2010功能区自定义中,在接下来的几篇文章中,我要介绍开发解决方案时可能要使用功能区进行的一些关键操作。然后直接潜水,一些功能区基础知识:

  • Ribbon 元素 必须 使用CustomAction标签以声明性XML进行定义-即使您实际上将使用代码来操作它们(例如,使其可见,启用/禁用等)
  • 的“control hierarchy” is ribbon > tab > group > controls – we’我将在这篇文章中探索所有这些
  • 单个按钮/控件不会出现在功能区上,也不会消失。这是关键的功能区原则,以避免“I’m 当然 这个按钮昨天在这里!”效果-相反,取决于上下文:
    • 可以显示/隐藏整个选项卡
    • 各个控件可以是 启用/禁用
    • [2011年9月–尽管SharePoint本身遵守此准则,但通过自定义,可以*完全隐藏功能区项目(尽管’d仍然说这是不推荐的,因为不一致的地方。本质上,您需要部署XML‘blanks out’ the definition – see 从服务器功能区上卸下按钮 在MSDN上获得更多详细信息。]
  • It’s not possible to add custom controls to the ribbon e.g. a custom .ascx/server control. 的list of controls defined by the ribbon can be found 这里 在MSDN文档中,包括按钮,复选框,颜色选择器,组合框,下拉列表,文本框,切换按钮等,但还包括一些时髦的元素,例如微调器,拆分按钮和弹出锚(可以在以下位置找到这些异类的定义)文档)。 FlyoutAnchor特别有趣,因为它将XML作为数据源,并且可以用来构建有趣的“pickers” e.g. with images – I’希望在以后的文章中详细介绍
  • 的definitions for the 盒子外面 ribbon 元素 are split across several files in the SharePoint root, with TEMPLATE\GLOBAL\XML\CMDUI.XML being the main one. 您 will likely spend significant time in this file looking for 例 s similar to what you’re building.

It’还值得特别考虑一下JavaScript如何使用功能区– it’经常使用,因为客户端上发生了很多事情。根据您对JavaScript的需求范围(例如,每页还是两页)以及您所需要的复杂性’为此,可以通过以下几种方式提供JavaScript:

  • 通过将其嵌入到声明性XML中(通过带有新‘Location="ScriptLink"’ 在 tribute) –这篇文章使用了这种方法,尽管在本系列的后面’ll显示下一个选项
  • 通过部署自定义.js文件,其中包含一些面向对象的JavaScript。这是用于更复杂的自定义的方法,您需要在其中创建客户端的对象“page component” in addition to your XML. 的页面组件 supplies the implementation for how your custom ribbon 元素 should handle various events (“commands”)。该对象需要从CUI.js中定义的现有CUI.Page.Component对象派生。与任何JavaScript文件一样,您可以在页面上使用几个选项进行引用。

在这篇文章中,我们’ll显示第一种添加JavaScript的方法,尽管在本系列的后面部分’ll show the use of a 页面组件.

示例-创建新的自定义标签

这是一个相当深入的示例, 因为有必要,它也涵盖了创建自定义组和控件的内容。另外,要用一颗石头杀死两只鸟,我认为最好看看新鸟。‘notifications’ 和 ‘status’客户端对象模型中的框架,用于将消息传递回SharePoint应用程序中的用户。首先我们’将逐步浏览我的自定义标签的外观,然后再实际操作。我有一个标题为“Chris’s custom tab” with 3 groups (“通知讯息”, “Add 状态 messages” 和 “Remove 状态 messages”),每个按钮中都有一些大小和图像不同的按钮(注意:尽管这些屏幕截图来自SP2​​010 beta时间范围,但此示例看起来仍然相同):

CustomRibbonTab

点击‘Notify hello’ button adds a transient message in the 通知 area (fades in from right 和 stays for 5 seconds by default):

 SP.UI.通知

点击‘Info 状态’ button shows a 状态 这次以默认颜色显示消息(此消息会一直显示在屏幕上,直到被另一个API调用删除为止):

SP.UI.Status_Info

点击‘Warning 状态’ button shows a 状态 message of a different color to indicate severity, I chose red:

SP.UI.Status_Warning

您可能还注意到了‘remove 状态’ buttons 有 become enabled when a 状态 message is present –这样的客户端检查可以通过链接一个‘CommandUIHandler’ with an ‘EnabledScript’ 在 tribute, as we’re about to see.

那么,需要什么XML来实现呢?在滚动浏览之前,请注意我’我采用了一些声明的复杂方法,因此我的示例尽可能提供了很多信息– most samples I’到目前为止,您只需在一个组中添加一个或两个按钮,然后’t specify the "’group template” details which determines how the controls in the group get laid out. This is fine for a button or 二 as you can just reference an 盒子外面 组模板, but if you want to do anything different you’有点卡住,所以希望这是很好的文档:

   1: <?xml version="1.0" encoding="utf-8"?> 
   2: <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> 
   3:   <  CustomAction   
   4:       Id="COB.SharePoint.Ribbon.CustomTab" 
   5:       位置="CommandUI.Ribbon" 
   6:       注册类型="List" 
   7:       注册编号="101"> 
   8:     <命令UIExtension> 
   9:       <命令UIDefinitions> 
  10:         <命令UIDefinition 位置="Ribbon.Tabs._children"> 
  11:           <Tab Id="COB.SharePoint.Ribbon.CustomTab" 
  12:                Title="Chris's custom tab" 
  13:                Description="Groups  和  controls will go in 这里" 
  14:                顺序="550"> 
  15:             < 缩放比例  Id="COB.SharePoint.Ribbon.CustomTab.Scaling"> 
  16:               <最大尺寸 Id="COB.SharePoint.Ribbon.CustomTab.NotificationGroup.MaxSize" 
  17:                        GroupId="COB.SharePoint.Ribbon.CustomTab.NotificationGroup" 
  18:                        Size="OneLarge"/> 
  19:               <最大尺寸 Id="COB.SharePoint.Ribbon.CustomTab.StatusGroup.MaxSize" 
  20:                        GroupId="COB.SharePoint.Ribbon.CustomTab.StatusGroup" 
  21:                        Size="TwoMedium"/> 
  22:               <最大尺寸 Id="COB.SharePoint.Ribbon.CustomTab.RemoveStatusGroup.MaxSize" 
  23:                        GroupId="COB.SharePoint.Ribbon.CustomTab.RemoveStatusGroup" 
  24:                        Size="TwoLarge"/> 
  25:               <规模 Id="COB.SharePoint.Ribbon.CustomTab.NotificationGroup.Scaling.CustomTabScaling" 
  26:                      GroupId="COB.SharePoint.Ribbon.CustomTab.NotificationGroup" 
  27:                      Size="OneLarge" /> 
  28:               <规模 Id="COB.SharePoint.Ribbon.CustomTab.StatusGroup.Scaling.CustomTabScaling" 
  29:                      GroupId="COB.SharePoint.Ribbon.CustomTab.StatusGroup" 
  30:                      Size="TwoMedium" /> 
  31:               <规模 Id="COB.SharePoint.Ribbon.CustomTab.RemoveStatusGroup.Scaling.CustomTabScaling" 
  32:                      GroupId="COB.SharePoint.Ribbon.CustomTab.RemoveStatusGroup" 
  33:                      Size="TwoLarge" /> 
  34:             </ 缩放比例 > 
  35:             <团体 Id="COB.SharePoint.Ribbon.CustomTab.Groups"> 
  36:               <Group 
  37:                 Id="COB.SharePoint.Ribbon.CustomTab.NotificationGroup" 
  38:                 Description="Contains notification items" 
  39:                 Title="通知讯息" 
  40:                 顺序="10" 
  41:                 模板="Ribbon.Templates.OneLargeExample"> 
  42:                 <Controls Id="COB.SharePoint.Ribbon.CustomTab.NotificationGroup.Controls"> 
  43:                   <Button 
  44:                     Id="COB.SharePoint.Ribbon.CustomTab.NotificationGroup.Notify" 
  45:                     命令="COB.Command.Notify" 
  46:                     顺序="10" 
  47:                     Image16by16="/_layouts/images/NoteBoard_16x16.png" 
  48:                     Image32by32="/_layouts/images/NoteBoard_32x32.png" 
  49:                     Description="Uses the notification area to display a message." 
  50:                     LabelText="Notify hello" 
  51:                     模板Alias="cust1"/> 
  52:                 </Controls> 
  53:               </Group> 
  54:               <Group 
  55:                 Id="COB.SharePoint.Ribbon.CustomTab.StatusGroup" 
  56:                 Description="Contains 'add 状态' items" 
  57:                 Title="Add 状态 messages" 
  58:                 顺序="20" 
  59:                 模板="Ribbon.Templates.TwoMediumExample"> 
  60:                 <Controls Id="COB.SharePoint.Ribbon.CustomTab.StatusGroup.Controls"> 
  61:                   <Button 
  62:                     Id="COB.SharePoint.Ribbon.CustomTab.StatusGroup.AddStatusInfo" 
  63:                     命令="COB.Command.AddStatusInfo" 
  64:                     顺序="10" 
  65:                     Image16by16="/_layouts/images/info16by16.gif" 
  66:                     Image32by32="/_layouts/images/info16by16.gif" 
  67:                     Description="Uses the 状态 bar to display an info message." 
  68:                     LabelText="Info 状态" 
  69:                     模板Alias="cust2"/> 
  70:                   <Button 
  71:                     Id="COB.SharePoint.Ribbon.CustomTab.StatusGroup.AddStatusWarning" 
  72:                     命令="COB.Command.AddStatusWarn" 
  73:                     顺序="20" 
  74:                     Image16by16="/_layouts/images/warning16by16.gif" 
  75:                     Image32by32="/_layouts/images/warning32by32.gif" 
  76:                     Description="Uses the 状态 bar to display a warning message." 
  77:                     LabelText="Warning 状态" 
  78:                     模板Alias="cust3"/> 
  79:                 </Controls> 
  80:               </Group> 
  81:               <Group 
  82:                   Id="COB.SharePoint.Ribbon.CustomTab.RemoveStatusGroup" 
  83:                   Description="Contains 'remove 状态' items" 
  84:                   Title="Remove 状态 messages" 
  85:                   顺序="30" 
  86:                   模板="Ribbon.Templates.TwoLargeExample"> 
  87:                 <Controls Id="COB.SharePoint.Ribbon.CustomTab.RemoveStatusGroup.Controls"> 
  88:                   <Button 
  89:                     Id="COB.SharePoint.Ribbon.CustomTab.RemoveStatusGroup.RemoveLastStatusButton" 
  90:                     命令="COB.Command.RemoveLastStatus" 
  91:                     顺序="10" 
  92:                     Image16by16="/_layouts/images/warning16by16.gif" 
  93:                     Image32by32="/_layouts/images/CRIT_32.GIF" 
  94:                     Description="Removes the last message from the 状态 bar." 
  95:                     LabelText="Remove last 状态 message" 
  96:                     模板Alias="cust4"/> 
  97:                   <Button 
  98:                     Id="COB.SharePoint.Ribbon.CustomTab.RemoveStatusGroup.RemoveAllStatusButton" 
  99:                     命令="COB.Command.RemoveAllStatus" 
 100:                     顺序="20" 
  101 :                     Image16by16="/_layouts/images/warning16by16.gif" 
 102:                     Image32by32="/_layouts/images/CRIT_32.GIF" 
 103:                     Description="Removes all messages from the 状态 bar." 
 104:                     LabelText="Remove all 状态 messages" 
 105:                     模板Alias="cust5"/> 
 106:                 </Controls> 
 107:               </Group> 
 108:             </团体> 
 109:           </Tab> 
 110:         </命令UIDefinition> 
 111:         <命令UIDefinition 位置="Ribbon.Templates._children"> 
 112:           <组模板 Id="Ribbon.Templates.OneLargeExample"> 
 113:             <Layout Title="OneLarge" LayoutTitle="OneLarge"> 
 114:               <Section Alignment="Top" Type="OneRow"> 
 115:                 <Row> 
 116:                   <ControlRef DisplayMode="Large" 模板Alias="cust1" /> 
 117:                 </Row> 
 118:               </Section> 
 119:             </Layout> 
 120:           </组模板> 
 121:         </命令UIDefinition> 
 122:         <命令UIDefinition 位置="Ribbon.Templates._children"> 
 123:           <组模板 Id="Ribbon.Templates.TwoMediumExample"> 
 124:             <Layout Title="TwoMedium" LayoutTitle="TwoMedium"> 
 125:               <Section Alignment="Top" Type="TwoRow"> 
 126:                 <Row> 
 127:                   <ControlRef DisplayMode="Medium" 模板Alias="cust2" /> 
 128:                 </Row> 
 129:                 <Row> 
 130:                   <ControlRef DisplayMode="Medium" 模板Alias="cust3" /> 
 131:                 </Row> 
 132:               </Section> 
 133:             </Layout> 
 134:           </组模板> 
 135:         </命令UIDefinition> 
 136:         <命令UIDefinition 位置="Ribbon.Templates._children"> 
 137:           <组模板 Id="Ribbon.Templates.TwoLargeExample"> 
 138:             <Layout Title="TwoLarge" LayoutTitle="TwoLarge"> 
 139:               <Section Alignment="Top" Type="OneRow"> 
 140:                 <Row> 
 141:                   <ControlRef DisplayMode="Large" 模板Alias="cust4" /> 
 142:                   <ControlRef DisplayMode="Large" 模板Alias="cust5" /> 
 143:                 </Row> 
 144:               </Section> 
 145:             </Layout> 
 146:           </组模板> 
 147:         </命令UIDefinition> 
 148:       </命令UIDefinitions> 
 149:       <命令UIHandlers> 
 150:         <命令UIHandler 
 151:             命令="COB.Command.Notify" 
 152:             命令Action="javascript: var notificationId =  SP.UI.通知 .addNotification('Hello from the notification area'); " /> 
 153:         <命令UIHandler 
 154:             命令="COB.Command.AddStatusInfo" 
 155:             命令Action="javascript:                    
 156:               var 状态Id = SP.UI.Status.addStatus('Quite important 状态 message');         
 157:               visibleStatusIds.push(statusId); 
 158:               enableRemoveStatusButton(); 
 159:               RefreshCommandUI();" /> 
 160:         <命令UIHandler 
 161:             命令="COB.Command.AddStatusWarn" 
 162:             命令Action="javascript: 
 163:               var warnStatusId = SP.UI.Status.addStatus('Very important 状态 message'); 
 164:               SP.UI.Status.setStatusPriColor(warnStatusId, 'red');   
 165:               visibleStatusIds.push(warnStatusId); 
 166:               enableRemoveStatusButton(); 
 167:               RefreshCommandUI(); " /> 
 168:         <命令UIHandler 
 169:             命令="COB.Command.RemoveLastStatus" 
 170:             启用脚本="javascript: enableRemoveStatusButton();" 
 171:             命令Action="javascript:             
 172:               SP.UI.Status.removeStatus(visibleStatusIds[visibleStatusIds.length - 1]);   
 173:               visibleStatusIds.pop(); 
 174:               enableRemoveStatusButton(); 
 175:               RefreshCommandUI();" /> 
 176:         <命令UIHandler 
 177:             命令="COB.Command.RemoveAllStatus" 
 178:             启用脚本="javascript: enableRemoveStatusButton();" 
 179:             命令Action="javascript:           
 180:               SP.UI.Status.removeAllStatus(true);        
 181:               visibleStatusIds.length = 0; 
 182:               enableRemoveStatusButton(); 
 183:               RefreshCommandUI();" /> 
 184:       </命令UIHandlers> 
 185:     </命令UIExtension> 
 186:   </  CustomAction  > 
 187:   <  CustomAction   
 188:     Id="COB.Command.RemoveLastStatus.CheckEnable" 位置="ScriptLink" 
 189:     ScriptBlock="          
 190:       var visibleStatusIds = [];                           
 191:       function enableRemoveStatusButton()  {   
 192:           return (visibleStatusIds.length > 0);        
 193:       }" /> 
 194: </Elements>

遵循XML顺序的一些关键点:

  • CustomAction :
    • 注意我有 CustomAction 元素– one for the ribbon 元素, the other for some JavaScript I want to use with my custom 元素. 这是approach mentioned earlier where the JavaScript is effectively embedded in your XML [旁注:你不’t 要进行功能区定制以利用这种方法-这种使用CustomAction的方法是向页面提供JavaScript的新方法,只要知道它将为Feature范围中的每个页面(例如站点/网站)添加,您就无法控制在页面的哪个位置将被注入。它确实使您能够通过功能停用取消JavaScript,这在许多情况下可能很有用)。
      • 的位置 在 tribute of CustomAction for ribbon 元素 should 总是 be “CommandUI.Ribbon”
      • 的位置 在 tribute of CustomAction for script is a 新 value, “ScriptLink”
    • 我的功能区选项卡的范围为 仅文档库– 这是礼貌的 注册类型="List" 注册编号="101" 属性(这正是将CustomAction定位到SharePoint 2007中的文档库时所做的事情,在此没有更改)
    • 以这种方式定位列表时,RegistrationId引用列表模板ID(例如,通用列表=100。文档库= 101 等)。– 这里’模板ID的完整列表) –例如,不可能以声明方式定位列表。 GUID或URL。因此,请考虑这可能会促使您在其他情况下可能没有创建列表模板,或者定义仅在特定情况下显示的上下文选项卡。
    • 注册类型的其他选项继续是“ContentType”, “ProgID” 和 “FileType”, but I’m pretty 当然 only “List”可以用于功能区元素,但是我’尚未测试,因此我保留错的权利! [2011年9月– 注册类型 =”ContentType也可以。]  如果您想要一个不同的作用域级别,则可以省略 注册类型 注册编号 属性并使用诸如SPRibbon.MakeTabAvailable()之类的代码有条件地显示功能区–通常这将是‘contextual’ tab. 在本系列后面的文章中,我将介绍如何为Web部件或自定义字段控件添加功能区自定义项,以进一步说明这一点。
  • 命令UIDefinition:
    • 另一个元素可能有多个–一个用于主要的自定义定义,一个用于每个“GroupTemplate”设置的元素(稍后会有更多介绍)。对于主要的“Location”此属性非常重要,因为它指定了定制应出现的位置。我的价值“Ribbon.Tabs._children” indicates I’我在里面加点东西“Ribbon.Tabs”由SharePoint定义的集合(通常在CMDUI.XML中)– “_children”是在功能区体系结构中添加到许多集合时使用的约定。我们’ll look 在 下一篇文章中如何在现有组中添加新组和控件,但作为一个简单的示例,将一个组添加到“Ribbon.Library.Groups._children”将使您的小组出现在小组的某个位置‘Ribbon.Library’标签,如下所示(具体取决于“Sequence”组号):
      色带库.Groups
  • 标签:
    • 的“Sequence”属性决定将我的标签放置在现有标签之间的位置(并且通常定义与该标签相比,该标签应该放在哪个位置’的兄弟姐妹)。开箱即用的值通常是10的倍数,偶尔是5的倍数,因此您的序列值应避免使用此类数字以避免冲突。通常你’我将需要找到您要定位的位置附近的周围元素的声明(通常在CMDUI.XML中)以找到合适的编号。
  • 缩放比例 (和儿童):
    • 本节定义在调整窗口大小时,元素的行为方式’没有足够的空间。你需要一个“MaxSize” 和 “Scale”您定义的每个组的元素。这些元素定义元素在以下位置时应位于的大小和布局“max”,以及窗口变小时要更改的内容–有效地,您可以根据窗口大小为控件提供多种布局(例如,对重要按钮进行优先级排序)。这是SharePoint功能区的一个非常酷和有用的功能。 [2011年9月– note that these 元素 should be sequenced 最大尺寸, 最大尺寸, 规模, 规模 (as mentioned in the comments below). This changed from beta to RTM, 和 is now reflected in my code sample above.]
  • 组:
    • 这是“功能区选项卡上的部分”这是您控件的容器–在上面的小图中,一个Group的例子是‘View Format’其中包含最左边的两个按钮。这里的关键是“Sequence”(与其他地方的交易相同),并且“Template” –这是对“GroupTemplate” element (which we’很快就会介绍)。本质上,这是将告诉功能区框架如何在该组中布置控件的链接。
  • 控制项:
    • 很明显,这是您要添加的任何控件的父节点,例如按钮,下拉菜单等。请注意,此处的每个控件都必须有一个“TemplateAlias” 在 tribute – this tells the framework exactly where to place the individual control within the 组模板 which is referenced.
    • Controls expose various 命令, via 在 tributes –一个按钮只是有一个“Command”点击时会触发的属性,而下拉菜单中还包含其他属性,例如“PopulateQueryCommand” 和 “QueryCommand". These link to “CommandUIHandler” 元素 or code defined in a JavaScript 页面组件.
  • 组模板:
    • 类似于定义HTML表,此部分提供控件的实际布局,对齐方式,控件大小等。要声明的每个控件都需要一个对应的“ControlRef”元素将与“TemplateAlias” value. [2011年9月–顺便说一句,我同意 安德鲁·康奈尔’s assertion that although you can avoid having to define 组模板s by using ones defined by Microsoft, this should be avoided since the template may not 总是 be available.]
  • 命令UIHandler:
    • 在这里,您可以定义在基本“Command”触发控件(例如,单击按钮)–但是请记住,这只是提供JavaScript的一种方式–另一种方法是使用页面组件(如本系列第三篇文章中所述)。使用这种方法,命令名称必须与Control元素上定义的名称匹配,并且“CommandAction”属性包含基本命令的脚本。您也可以使用“EnabledScript”属性以添加一些脚本,该脚本决定是否应启用控件– this is how my '’remove 状态’仅在有要删除的消息时启用按钮。
    • 由于所有JavaScript都被添加到同一页面,因此’ll see in my sample it is possible to declare variables which get used by other JavaScript provisioned by a different 命令UIHandler –再说一次,虽然顺序是确定的,但是您无法控制将脚本添加到整个页面的位置(在开始时<body>标记),因此如果您需要在DOM完成时运行代码,’d必须采取措施在适当的时间调用您的代码–这实际上是页面组件方法,本系列后面的内容将对此进行更多介绍。

希望您觉得这有用。下次我们’ll take a quick look 在 adding items to existing ribbon locations, before moving onto working with JavaScript 和 页面组件s etc.

55条评论:

史蒂夫 说过...

我认为功能区UI的复杂性将成为SP2010对最终用户的主要挑战之一。它'是此版本成功的少数风险因素之一。很高兴看到SharePoint社区的一些领导人提早解决此问题,并提供了解决方案和选项。很棒的内容!

彼得·克奈尔 说过...

很棒的帖子,我试图建立一些自定义的功能区按钮,以允许我们插入到文档管理系统的链接。您有机会从xml文件中删除行号(或仅使其可供下载)。这将使他们的实验变得容易得多:)
我使用了您有关样式和标记样式的另一篇文章,并且效果很好-为我节省了很多时间。
感谢您的精彩博客。

克里斯 O'Brien 说过...

@Peter Kneale,

好点,我想我的样本是'为阅读而优化' ;) I'请尝试在第二天或第二天对行号做一些事情。

克里斯.

富兰·谢赫(Furqan Shaikh) said...

有关功能区定制的精彩入门文章。
我正在研究SP 2010 Beta版。元素只有一个元素,这与您的XML也具有组不同。我想念什么吗?任何帮助表示赞赏。

谢谢,
富良

克里斯 O'Brien 说过...

@Furqan,

唐'别忘了你只需要一个'Groups'元素(如果要定义) 组。如果您要定位现有的组(根据我的系列的第二篇文章- 将功能区项目添加到现有选项卡/组中),你不会't 有 a 'Groups' element.

那有意义吗?

克里斯.

托尼·弗兰科拉 说过...

克里斯,

这是一篇很棒的文章,非常有帮助!

我在代码中遇到了一些问题,可能是因为我正在使用beta2吗?

1) I had to reorder sub-elements of the group element element 和order them: 最大尺寸-MaxSize-MaxSize-Scale-Scale-Scale
2) Also the Remove 状态 buttons are note enabled after 状态 is posted, they stay in disable state all the time.

克里斯 O'Brien 说过...

@Toni,

感谢您的客气话。不知道为什么会有几个问题,尽管现在我可以'不记得我是在beta 2还是RC上编写此样本的,可能就是这样。

建议确保您'但是,每次更改后都要重新清除浏览器缓存-有时我被抛出一个循环,并且想了一会儿某些标记是错误的,结果是缓存再次使我迷惑,当我清除缓存时,事情开始起作用。使用功能区时一定要注意:)

克里斯.

杰森·洛坎(Jason Lochan) said...

感谢您将我指向TEMPLATE \ GLOBAL \ XML \ CMDUI.XML!巨大的帮助

安迪·范德里奇 said...

Does anyone know if it is possible to add ribbon 命令 for a specific custom list template only?
我使用自定义列表模板开发了自定义功能,并尝试仅针对基于此模板的列表应用功能区自定义,但无济于事。尝试使用RegistrationId = myID并尝试使用自定义内容类型。默认列表模板(自定义列表等)的功能区自定义效果很好。

我首先想到的是Beta版存在问题,但事实并非如此'也可以在RTM中使用。有什么想法吗?

未知 说过...

感谢您的精彩帖子。我使用您的代码作为基础,但是发现在部署和测试功能区时不会加载任何图像。还有其他人遇到吗?有一个简单的解决方案吗?还有一种简单的方法可以使功能区始终显示,而不管用户去站点的哪一部分?

谢谢,
标记

胜利者 said...

此方法是否仍默认允许将SP 2010权限应用于任何新的选项卡或按钮?

克里斯 O'Brien 说过...

@胜利者,

I'm not 当然 I fully understand the question, but the implementor/developer is responsible for implementing any security-trimming of ribbon controls. As an 例 , for a button the 启用脚本 在 tribute is used to point to some JavaScript which you write to decide whether the button should be enabled or not for the current user.

HTH,

克里斯.

Shai Petel 说过...

Hi 克里斯!

很棒的帖子,只有您在发布的代码中有两个错误:

1. 您r enable script will not get fired after adding 状态 messages. 您 有 to call "RefreshCommandUI();" in order to get SharePoint to reevaluate the button 状态.
实际上,您应该调用它而不是调用enableRemoveStatusButton();。

2.第二个问题更合乎逻辑,"latestId"实际上应该存储一个id数组',因此一旦您删除了最新的,它仍将具有上一个。数组中的邮件。

除此之外-感谢您的精彩文章。真的很喜欢阅读它。

克里斯 O'Brien 说过...

@Shai,

有用的反馈,谢谢!关于第二点,我想我当时不是'太担心支持多条消息了'并不是真正的逼真演示(我想保持简单),但是是的,我同意。

我对第一点很感兴趣-我'm assuming RefreshCommandUI() would trigger the 启用脚本 for *all* current ribbon 元素, not just one? If so, I wonder - is it a good pattern to use this when you know only one element has changed? I know it'在客户端上,但仍然'不必要的处理更多吗?

Or is the bug something 大ger than my understanding?

好讨论,谢谢:)

克里斯.

Shai Petel 说过...

Hi 克里斯,

的issue is that you want to click a ribbon button (add 状态 message) 和 in that event you change the flag for enabling other ribbon buttons.

Thing is, the ribbon does not re-evaluate the button 状态 in that time.

因此,在RTM版本中,除非我按一下更新(例如单击Web部件),否则我一直将按钮保持禁用状态。

的refresh function does not run on all of the ribbon, it does 2 things:
1. Show / Hide 语境 tabs
2.仅在当前活动选项卡中启用/禁用控件

但是我不'无论如何都看不到使之更有效率,因为您永远无法知道还有谁在听(其他控件可能是由其他开发人员提供的)

克里斯 O'Brien 说过...

@Shai,

哦,哇-我进行开发时,这些按钮确实表现出预期,但是自从2010年1月以来,这显然不在RTM上。我猜发布之间有些变化。

在这种情况下'我还要感谢您的更正-我想我们得出结论,在这种情况下,需要RefreshCommandUI()。

谢谢,

克里斯.

路易斯·埃斯特万·瓦伦西亚 说过...

我在xml文件上有一个警告:

Warning 1 的element 'Scaling' in namespace 'http://schemas.microsoft.com/sharepoint/' has invalid child element 'MaxSize' in namespace 'http://schemas.microsoft.com/sharepoint/'. 清单 of possible 元素 expected: 'Scale, LowScaleWarning' in namespace 'http://schemas.microsoft.com/sharepoint/'. K:\Users\Administrator\Documents\Visual Studio 2010\Projects\SlnSharepoint2010\EmptySharePointProject1\CustomRibbonElements\Elements.xml 19 16 EmptySharePointProject1

任何想法 ?

谢谢

克里斯 O'Brien 说过...

@路易斯,

嗯那个'很奇怪-如果您查看CMDUI.XML,'会看到微软自己使用了很多'MaxSize'功能区XML中的元素(I'刚刚检查了RTM)。

可能是XML中使用了命名空间吗?您是否正在开发RTM版本?

谢谢,

克里斯.

路易斯·埃斯特万·瓦伦西亚 说过...

Hello 克里斯, as somebody else said on the comments I fixed this by changing order,
最大尺寸,MaxSize,MaxSize, 缩放比例 , 缩放比例 , 缩放比例

是的,我正在使用RTM

克里斯 O'Brien 说过...

@路易斯,

好东西-那's certainly the sequence Microsoft use for their 元素.

克里斯.

ഇക്ബാല്‍ കാഞ്ഞിരമുക്ക് 说过...

你好

如何使用功能区创建新的批准任务内容类型。

这是针对Project Server 2010工作流的。有一个默认的Project Server工作流任务表单。我正在寻找包括批准/拒绝和发送给发起者的客户。

你能帮助我吗?
提前致谢
伊克巴尔克

2010年初 said...

(能够'相信我单击“发布”后浏览器就会死机。如果这是两次发布,请忽略)
I'我为自己不得不问这个问题而感到ham愧,但请忍受我。我想尝试您的例子,但我可以'弄清楚我到底在哪里'我应该添加此XML摘录?是进入cmdui.xml还是应该创建一个新的XML文件?我本来以为第二个'在这种情况下,如何使SP连同cmdui.xml一起加载我的XML文件?
我知道这可能是基础知识,但是如果您可以给我一个快速的答案,我'd be indebted.
在此先感谢您,祝您周末愉快。

克里斯 O'Brien 说过...

@ BeginningSharePoint2010,

其实那个's a great beginner'的问题,文章没有道歉't deal with it. 的XML will be in a 新 XML file - cmdui.xml is an "out-of-the-box"SharePoint文件和大多数文件一样,绝对不能修改。

使您的自定义XML文件成为'known'通过SharePoint,您必须创建一个称为 特征 -这有一个feature.xml文件,其中包含几个'elements', such as the CustomAction shown 这里 to modify the ribbon. 您 can create a 特征 easily in Visual Studio 2010 by right-clicking on the 特征s item 和 selecting 'New 特征'.

As you can probably tell, creating 特征s requires an element of development skills 和 (unless you'疯狂,并在记事本中完成操作)使用Visual Studio。

希望这可以帮助您找到一些链接和术语,以进行进一步的阅读。随便问更多问题。

谢谢,

克里斯.

2010年初 said...

非常感谢您的及时答复!我可以'相信您能尽快回答我!再次感谢!一世'我像疯子一样在SharePoint博客中进行挖掘:)很多知识需要消化,但我'一天到达那里:)

埃斯瓦拉哈里 说过...

克里斯你好

对于SP 2010初学者来说,这是一篇很棒的文章,它介绍了Ribbon功能。

1.I实现了示例中给出的功能区控件。
2.一切正常,但是在将pageviewer webpart添加到页面后出现了问题。
添加webpart后,选项卡中的所有按钮都被禁用,处于启用模式上。

请给我,如果您有任何解决方案

谢谢
埃什瓦尔

亨里克·安德森(Henrik Andersson) 说过...

@ShaiPetel

我已经张贴了 有关如何根据字段值和权限禁用和启用按钮的信息。

也许它可以帮助您朝正确的方向发展?

问候,
// Henrik

马丁 说过...

克里斯,

首先,感谢出色的博客系列。这对我帮助很大!

您是否知道如何扩展功能区上现有(OOB)按钮的行为?

我需要扩展'Cancel Approval'按钮,以取消批准工作流程和自定义工作流程。这可能吗?

问候,
马丁

克里斯 O'Brien 说过...

@马丁,

好问题。我觉得你'd在这种情况下,要做的就是隐藏原始按钮,然后在其中放一个您自己的按钮。我可以'除了对原始工作流程进行更改之外,没有其他方法可以扩展原始功能。

您'd使用HideCustomAction从功能区中删除原始按钮。

HTH,

克里斯.

马丁 说过...

感谢您的反馈!不幸的是,我无法使用HideCustomAction元素。这将删除按钮,这将导致错误(SharePoint中的某些内容取决于按钮的存在)。

I've尝试使用CSS删除它,但是"big"按钮(菜单的根目录或其他可能被调用的菜单)仍在显示,我不知道如何更改。

我将重新设计解决方案,所以我不必这样做...


问候,
马丁

匿名 said...

Great job 克里斯.
我正在自定义“日历”列表的“查看项目”功能区。也就是说,我需要移动"Export Event" from Custom 命令s to any of the View groups.
To give more description: When you hit View 项目 a 新 window shows up with View 和 Custom 命令s tabs. One of the project requirement is to move (or copy) the 出口活动 to View tab. Here I can create separate group on View tab. But I am not required to do this. I tried to get the location of this Ribbon Control. What is the location of this control 和 how do you customize this? Any help please?

匿名 said...

很好的帖子!

我有一个小问题。我是一个真正的初学者,所以这可能是一个愚蠢的问题。

我在项目中创建了一个XML文件,并粘贴了您的代码。我还创建了一个功能,但是该功能没有"find"我的XML文件,因此无法将其添加到功能中。

极客 说过...

Hi 克里斯,

很棒的帖子。这对我帮助很大。我对SharePoint 2010相当陌生&想要严重地自定义功能区。我知道功能区组件存储在GLOBAL文件夹中的XML文件中。但是,如果要自定义功能区,则需要在此处上传新的XML,或者需要更改CMDUI.XML本身。我读了你的整个帖子 &这是唯一不清楚的事情。请您包括整个过程,即我们需要做些什么来自定义功能区。将新的xml上载到某个地方或修改现有的XML。

谢谢& 问候,
潘妮

克里斯 O'Brien 说过...

@Panny,

不,你不应该't修改CMDUI.XML-请查看我对@ BeginningSharePoint2010的回答,以了解如何使用'Feature'为SharePoint提供自定义XML。

谢谢,

克里斯.

克里斯 O'Brien 说过...

@匿名,

您 can use 特征 Explorer in Visual Studio 2010 to control which 元素 files are referenced by a 特征.

HTH,

克里斯.

匿名 said...

忽略我的最后一条消息。我能够使用RefreshCommandUI使其工作。应该先阅读反馈线程。

谢谢,
杰克

克里斯 O'Brien 说过...

@杰克

很高兴听到您被排序-RefreshCommandUI()确实是SP2010 RTM版本中的关键。

干杯,

克里斯.

附言抱歉,您的原始问题似乎已被我的博客主机丢弃。 (对于其他读者,这只是说明样本不是'不能像广告中所说的那样工作,并且正如在这些评论中指出的那样's需要RefreshCommandUI()。

匿名 said...

I 有 an issue with the OOTB Ribbon 命令s. I am creating a 新 Master Page. Nothing 新 这里 I 有 done literally hundreds of them. However, I now amd seeing a postback error. Realted to a few of the ribbon 元素. Show Ribbon,Hide Ribbon 和 the edit page buttons. I 有 not added a 新 ribbon. First Time, I 有 seen this: 无效的回发或回调参数。 我不知道这是怎么造成的?

未知 说过...

Hello 克里斯, first of all great article. It was very helpful. But I 有 small problem I created custom group 和 button for ribbon in Library/Documents 语境 tab 和 it is visible from sites in Library category i.e. shared documents site but it is not from any other site when Library 语境 tab appear. I dont know if it is good idea to put my code in comment right 这里 so I will not. But maybe you know what the problem might be?
问候
麦可

克里斯 O'Brien 说过...

@迈克尔,

当然-我'如果您在此处发布详细信息,请尝试提供帮助。

谢谢,

克里斯.

未知 说过...

So basically I want to add 新 group to Library/Documents 语境 tab. My custom action is defined like this:

http://pastebin.com/4FEUR5de

但是,该组仅在图书馆站点(即共享文档)中可见。我希望每次显示“库”上下文选项卡时,它在每个站点页面中都可见。我应该更改什么以使其在所有“库”上下文选项卡中可见?

问候
麦可

未知 说过...

再次您好,我已经解决了问题:我删除了RegistrationID和RegistrationType标记,执行了iisreset并清除了浏览器缓存,并且可以在每个位置看到我的组。

问候
麦可

克里斯 O'Brien 说过...

@迈克尔,

太好了,很高兴听到您排序。

克里斯.

爱丽儿 说过...

Hi 克里斯, thanks for this great content.

I'我按原样尝试一下,只是复制&粘贴,当我导航到101文档库时,选项卡旋转显示"Loading..." message.

任何想法?

爱丽儿 说过...

Nevermind, found the problem... missing a 组模板. After re-adding that, working correctly. Great post 克里斯. 您 can simply ignore my prev question.

xzy2ob 说过...

你好

的"full lists of ids"不再存在:

http://simeonlobo.wordpress.com/2008/02/27/sharepoint-list-template-ids/http://simeonlobo.wordpress.com/2008/02/27/sharepoint-list-template-ids/http://simeonlobo.wordpress.com/2008/02/27/sharepoint-list-template-ids/

现在在哪里可以找到?

克里斯 O'Brien 说过...

@All-指向模板ID列表的链接现已更新,其他许多方面也是如此。非常感谢您的反馈!

克里斯.

匿名 said...

Great Work 克里斯.It helped me a lot in customizing the SP ribbon

匿名 said...

我和我的同事正在尝试简单地学习如何添加自定义组,感谢您立即添加3页xml。

匿名 said...

优秀的邮递员,对我有很大帮助

未知 说过...

很棒的帖子!只是一个简短的问题,无论您在哪个列表/库中,都可以使选项卡组始终可见。如果只在elements.xml文件中会比较喜欢,但是如果需要代码,那将是个好消息!与往常一样,您的帖子非常有用!

克里斯 O'Brien 说过...

@邪恶的天才,

这可以通过按内容类型注册您的自定义并使用'Item'作为内容类型。因此,我认为您在CustomAction上'll need:

注册类型 ="ContentType" 注册编号="0x01"

HTH,

克里斯.

SPEvilGenius said...

克里斯,

有一点晚!但是是的,一切都解决了!现在加载的问题!是否可以使用纯JavaScript而不使用声明性XML来完成所有这些工作?对于某些客户,没有设计师或无法访问HIVE !!

问候,
丹·沃克
SPEvilGenius

匿名 said...

一如既往的好帖子。
谢谢。

未知 说过...

Hi 克里斯, this is awesome post. Very helpful. Saved me loads of efforts. I searched for articles on ribbon customization for good 二 weeks, but found nothing that matched my requirements. Certainly you are a great asset to the share point community.

杰森·邓巴(Jason Dunbar) 说过...

Yep, six years later, people are still 找ing this useful.

谢谢-希望你're well :-)