自定義和擴展 SharePoint 2010 Server 功能區
了解構成 SharePoint 2010 服務器功能區的組件以及如何通過演練兩個功能區自定義項方案來自定義功能區。
適用范圍: Microsoft SharePoint Foundation 2010 | Microsoft SharePoint Server 2010 | Microsoft Visual Studio 2010 中的 SharePoint 開發工具
目錄
- SharePoint 2010 Server 功能區簡介
- SharePoint 2010 Server
功能區體系結構
- 自定義 SharePoint 2010 Server 功能區
- 自定義內置 SharePoint 2010 Server
功能區組件
- 創建自定義 SharePoint 2010 Server
功能區組件
- 自定義 SharePoint 2010 Server
功能區開發提示和技巧
- 結論
- 其他資源
下載本文附帶的代碼:MSDN 示例 - 自定義和擴展 SharePoint 2010 Server 功能區(該鏈接可能指向英文頁面)
SharePoint 2010 Server 功能區簡介
隨著 2007 Microsoft Office system 的發布,Microsoft 引入了一個稱作“功能區”的新用戶界面結構,它代替了以前的應用程序下拉菜單和工具欄。大量的調查研究表明,某些應用程序(例如,Microsoft Word)包含太多命令,導致用戶難以找到所需的命令,功能區正是為解決這個問題而引入的。
功能區的前提是提供一個更加以結果為導向的界面。用戶可將精力集中在他們執行的操作上,系統將僅顯示用戶可在特定時間執行的操作的命令。例如,當用戶明確地鍵入文本并且未選擇圖像或表時,沒有理由為用戶提供與文檔中的表或圖像交互的命令。但是,通過使用“插入”選項卡,用戶可輕松添加表或圖片。僅在用戶選擇了表或圖片時,才會出現新的命令結構。當表或圖片不再是焦點時,這些命令將消失。
在 2007 Microsoft Office system 中,已在 Microsoft Word、Microsoft Excel 和 Microsoft PowerPoint 中實現功能區。Microsoft 在此基礎上進行了擴展,并已將功能區添加到所有 Microsoft Office 2010 應用程序(包括 Microsoft OneNote 2010、Microsoft Access 2010 和 Microsoft InfoPath 2010)。
類似于 Microsoft Office 客戶端,SharePoint 用戶在查找控件以完成其工作上遇到了類似的難題。命令在頁面中的多個位置存在,從“網站操作”菜單到管理 Web 部件或到列表中的“編輯控件塊”(ECB) 菜單。圖 1 演示了對 Windows SharePoint Services 3.0 網站中的用戶可用的所有菜單。
圖 1. Windows SharePoint Services 3.0 中的菜單和命令

在 Microsoft SharePoint 2010 中,Microsoft 已將服務器功能區添加到 SharePoint,以解決用戶在使用 Microsoft Office 客戶端中的許多命令時遇到的難題。已將所有命令和菜單項從 SharePoint 中的主工作區向上推入始終固定到瀏覽器窗口頂部的功能區。2007 Microsoft Office system 的用戶或已實現功能區的其他應用程序的用戶會發現,由于 SharePoint 功能區與 Office 客戶端功能區非常相似,因此調節 SharePoint 功能區非常輕松。該功能區在外觀、工作方式和執行的操作上與 Office 功能區類似,并且具有與 Office 功能區相同的控件。Office 功能區和 SharePoint 服務器功能區之間的唯一差異與技術有關;例如,與在桌面(胖客戶端)體驗中一樣,難以在 Web(瘦客戶端)體驗中顯示不同的字體。
SharePoint 2010 中的功能區是基于與 Office 客戶端功能區類似的體系結構構建的。Microsoft 使用此體系結構在 SharePoint 2010 中實現默認功能區。此體系結構還允許第三方開發人員自定義和擴展 SharePoint 中包含的現有功能區組件以及創建命令結構。
本文介紹了 SharePoint 服務器功能區的組件,以便您了解功能區的構造方式。然后,說明并演示了開發人員自定義和擴展功能區的方式。SharePoint Foundation 2010 通用參考中有一節專門介紹了功能區,并包含各種自定義演練。在自定義功能區時,建議您將本文與 SharePoint Foundation 2010 通用參考(具體而言是 SharePoint Foundation 中的服務器功能區一節)配合使用。
SharePoint 2010 Server 功能區體系結構
默認功能區由 SharePoint 構建且基于作為主安裝的一部分的單個文件。此文件是在路徑 {SharePoint Root}\TEMPLATE\GLOBAL\XML\CMDUI.XML 中找到的全局網站定義的一部分。此文件包含 SharePoint Foundation 2010 中的功能區組件(例如,“瀏覽”、“頁”、“列表”、“庫”和“文檔”選項卡)的定義。
雖然 CMDUI.xml 文件包含所有核心服務器功能區組件,這與對功能區實現其他自定義的方式無關。SharePoint 功能用于實現對功能區的其他更改。例如,Microsoft SharePoint Server 2010 包括許多需要功能區修改的任務,例如,與“企業內容管理”、“表單服務”和商業智能相關的任務。所有這些更改都是通過使用 SharePoint 功能實現的。SharePoint 開發人員還可通過使用功能來自定義功能區,如本文后面的創建自定義 SharePoint 2010 Server 功能區組件中所述。
SharePoint 2010 擴展了功能架構(具體而言為 <CustomAction /> 元素),使其成為所有功能區自定義項的工具。通過將 Location 屬性設置為 CommandUI.Ribbon 并添加一個 <CommandUIExtension /> 子元素,可以做到這一點。SharePoint 2010 SDK 概述了服務器功能區 XML。
以下各節說明了功能區的兩大核心部分:構成視覺體驗的組件以及在單擊功能區中某個控件時運行的代碼。
SharePoint 2010 Server 功能區組件
SharePoint 2010 服務器功能區包含各種組件,如圖 2 所示。
圖 2. SharePoint 2010 Server 功能區組件

圖中的標注號指向以下特定組件:
- 選項卡
- 組
- 控件
- 上下文選項卡組
后面幾節簡要介紹了這些組件及其使用。
SharePoint 2010 Server 功能區上的選項卡
選項卡是服務器功能區的根。它們包含一個或多個組,并包含相似的功能。例如,在圖 2 中,當前選定的“頁”選項卡包含與使用當前頁相關的功能。
SharePoint 2010 Server 功能區上的上下文選項卡組
上下文選項卡組用于提供當前上下文的非全局功能(例如頁)。它們僅在遇到某些情況時出現且包含一個或多個選項卡。
例如,圖 2 中的功能區演示“庫工具”上下文選項卡組,該組僅在文檔庫中顯示或(在此示例中)當選中與文檔庫關聯的當前頁面上的“列表視圖 Web 部件”時顯示。
上下文選項卡組會在功能和菜單選項不可用時為用戶隱藏它們,并在功能和菜單選項可用時為用戶顯示它們。上下文選項卡組的其他示例包括在編輯 wiki 頁時出現的“編輯工具”上下文選項卡組,或在編輯模式下選中某張圖片時出現的“圖片工具”上下文選項卡組。
SharePoint 2010 Server 功能區上的組
功能區中的每個選項卡均包含一個組或一系列組。組用于將控件與相似功能關聯。每個組均與一個模板關聯,該模板根據功能區縮放定義組的布局及其顯示方式。功能區縮放是指功能區中有太多控件要顯示的情況,例如,當瀏覽器未處于全屏最大化顯示狀態而只是處于窗口狀態時。
SharePoint 2010 Server 功能區上的組模板
組模板用于為組中的控件定義不同的布局選項。Microsoft 在 CMDUI.xml 文件中包含 29 個組模板(若要查找這些模板,請在此文件的結尾搜索元素 <RibbonTemplates />)。
SharePoint 2010 Server 功能區上的控件
如果用戶未選擇或單擊任何項,則功能區將是不完整的。控件是用戶可與之交互的功能區內部的項??丶v留在組中,其中包括按鈕、切換按鈕、復選框、文本框和許多其他控件。有關所有可用控件的完整列表,請參閱服務器功能區的體系結構。
每個控件定義包含一個 Command 屬性,在單擊或選中該屬性時,會告知功能區基礎結構要執行的操作。
SharePoint 2010 中的服務器功能區命令
服務器功能區使用命令處理用戶執行的單擊或選擇操作。熟悉命令基礎結構在 Windows Presentation Foundation 或 Microsoft Silverlight 4 中的工作方式的用戶會發現它等同于服務器功能區命令基礎結構。每個命令都進行了命名,并在控件中引用相應的名稱。最重要的是,這些命令包含兩條非常重要的詳細信息:
- 當前命令是否可用 例如,“刪除”命令僅在文檔庫中或選中文檔時可用。
- 應運行的代碼 例如,“刪除”命令可能會使用
SharePoint 2010 客戶端對象模型來刪除列表中的項、顯示已刪除文檔通知并在頁面上刷新列表視圖 Web 部件。
主題服務器功能區的體系結構包含與命令基礎結構的工作方式相關的其他詳細信息。
通過使用 ECMAScript(JavaScript、JScript) 編寫服務器功能區中的命令??赏ㄟ^兩種方式實現命令:
- 通過命令 UI 處理程序
- 通過頁面組件
以下各節中對這兩個選項進行了說明,并討論了每個選項的優缺點。通常,簡單且相對較小的命令適用于命令 UI 處理程序選項。但是,較為復雜且需要實現大量 ECMAScript 的命令可能更適用于頁面組件。本文后面的文檔庫示例中使用的示例功能區自定義項演示如何使用每種技術來執行完全相同的操作。
使用命令 UI 處理程序實現服務器功能區命令
命令 UI 處理程序是通過結合使用聲明性標記和 ECMAScript 來實現的。在定義功能區自定義項(使用 <CommandUIExtension /> 元素進行定義)的同一 Feature 元素清單中使用 <CommandUIHandler /> 元素定義這些處理程序。此元素包含以下三個屬性:
- Command 將在控件中引用的命令名稱。
- CommandAction 觸發該命令時執行的
ECMAScript。
- EnabledScript ECMAScript,服務器功能區命令基礎結構調用它來確定該命令是否可用。此腳本應返回一個布爾值,如果該命令可用,則為
TRUE;如果該命令不可用,則為
FALSE。如果該命令不可用,則功能區基礎結構會將功能區中的該命令灰顯,并且在用戶選擇該命令時不調用它。
使用命令 UI 處理程序的優點
通常,對于大多數開發人員而言,命令 UI 處理程序更易于編寫和管理。由于這些處理程序是以聲明方式定義的,因此功能區框架會將腳本添加到其中的引用控件需要命令的任何頁面。
使用命令 UI 處理程序的缺點
命令 UI 處理程序的缺點之一是,當它們包含大量自定義 ECMAScript 時會變得難以管理、調試和進行故障排除。此外,由于這些處理程序會作為內聯腳本塊添加到每個頁面中,因此無法通過瀏覽器對其進行緩存,并且每次都必須下載,從而增加了整體頁權重。
使用頁面組件實現服務器功能區命令
除了使用命令 UI 處理程序外,還可以使用頁面組件。頁面組件是一個在外部腳本庫 (.js) 文件中定義的 ECMAScript 對象。該對象實現了幾個屬性和方法,它們將告知服務器功能區命令基礎結構如何初始化該對象、該對象可處理哪些命令以及某個特定命令是否可用,并可在頁面組件接收焦點或失去焦點時做出響應。
必須將此腳本文件添加到顯示功能區自定義項的同一頁面中。可通過多種方法來實現這一點。第一種方法是,使用 SharePoint 2010 中的新 <CustomAction ScriptSrc="" /> 功能,根據功能的范圍將庫添加到網站、網站集、Web 應用程序或服務器場中的所有頁面。另一種方法是,從自定義應用程序或網站頁面 (.aspx)、自定義用戶控件 (.ascx) 或自定義服務器控件內的托管代碼添加腳本。以下代碼示例將向 Web 部件內的頁面添加頁面組件文件。
private void LoadAndActivateRibbonContextualTab() { SPRibbon ribbon = SPRibbon.GetCurrent(this.Page); // Ensure ribbon exists. if (ribbon != null) { // Load dependencies if not already on the page. ScriptLink.RegisterScriptAfterUI(this.Page, "SP.Ribbon.js", false, true); // Load and activate contextual tab. ribbon.MakeTabAvailable("Ribbon.PropertyChangerTab"); ribbon.MakeContextualGroupInitiallyVisible("Ribbon.WebPartContextualTabGroup", string.Empty); } }
使用頁面組件的優點
由于所有 ECMAScript 都位于外部腳本庫中,因此更易于對頁面組件(而非命令 UI 處理程序)進行管理、故障排除和調試(Microsoft Visual Studio 2010 腳本調試器可設置斷點并附加到庫)。另外,由于它是一個外部庫,因此瀏覽器可緩存該庫,而無需每次在頁面上引用它時向它發出請求。
還可利用頁面組件更好地控制命令,因為它們可通過接收或丟失焦點來啟用或禁用頁面組件,并處理上述每種情況下發生的事件。
另外,由于它們是外部庫,因此,一個頁面組件可處理多個控件的命令,并可在各種功能區自定義項中重用。
使用頁面組件的缺點
相對于使用命令 UI 處理程序,使用頁面組件的一個缺點是需要大量腳本。這主要是因為開發人員在頁面上構建、注冊和初始化一個腳本對象。另外,不熟悉面向對象的 ECMAScript 技術的開發人員會發現要做到這一點會有點難度。
使用頁面組件的另一個缺點是,必須將其添加到頁面,因為這不是由功能區命令基礎結構處理的。
自定義 SharePoint 2010 Server 功能區
當開發人員希望自定義 SharePoint 服務器功能區時,會為其提供兩個選項。以聲明方式或以編程方式應用自定義項。使用功能實現本文前面所述的聲明性方法;具體而言,帶 <CommandUIExtensions /> 子元素的 <CustomAction /> 元素。
編程方法包括將聲明性構造作為字符串添加到服務器功能區對象中。本文的其余內容將重點說明聲明性方法,因為也可將這些技術應用于編程方法。SharePoint 2010 SDK 包含有關以編程方式自定義功能區的演練:演練:使用上下文選項卡創建自定義 Web 部件。
自定義內置 SharePoint 2010 Server 功能區組件
開發人員可通過三種方式自定義功能區:
- 向功能區添加組件(選項卡、上下文選項卡組、組和控件)。
- 在功能區中修改現有組件。
- 從功能區中刪除現有組件。
可以聲明方式執行所有這三個選項。服務器功能區 XML 演示了不同的元素。服務器功能區的聲明性自定義項演示如何向功能區添加三個常用組件。
修改和移除組件(例如,選項卡、組和控件)的方式與修改和移除相同架構元素的方式很類似。通過重復元素的 ID 并替換其內容來修改元素,這與內容占位符在 Microsoft ASP.NET 2.0 母版頁中的工作方式類似。移除操作與修改操作相同,只不過容器保留為空。有關詳細信息,請參閱服務器功能區的聲明性自定義項。
創建自定義 SharePoint 2010 Server 功能區組件
以下兩節演示如何自定義 SharePoint 2010 服務器功能區。這兩個演練都使用了各種技術,并對每個組件進行了詳細說明。有關這兩個演練的示例代碼,請參閱 MSDN 示例 - 自定義和擴展 SharePoint 2010 Server 功能區(該鏈接可能指向英文頁面)。此示例代碼只需要一個 SharePoint Foundation 2010 網站集。
第一個示例為 WebPartRibbonContextualTab(如圖 3 所示),它演示如何創建使用以下功能區自定義項的自定義 Web 部件:
- 上下文選項卡組
- 自定義選項卡
- 自定義組
- 命令 UI 處理程序
- 僅當 Web 部件位于頁面上時激活上下文選項卡組
- 單擊功能區上的按鈕時觸發并處理服務器端回發。
圖 3. 帶上下文選項卡組的 Web 部件

第二個示例為 ApplyDocumentPrefixRibbon(如圖 4 所示),它演示如何實現以下自定義項和技術:
- 現有功能區選項卡中的自定義組。
- 具有不同布局選項的自定義組模板。
- 執行相同操作的兩個自定義命令,只不過其中一個命令是通過命令 UI
處理程序實現的,而另一個命令實現自定義頁面組件:
- 除非選中庫中的一個或多個文檔,否則將禁用命令。
- 單擊時,命令將打開一個對話框,傳遞選定文檔并根據用戶輸入執行操作。
- 在對話框的工作完成后,該對話框將關閉,同時命令將顯示一條通知消息并刷新列表視圖 Web
部件而非整個頁面。
- 除非選中庫中的一個或多個文檔,否則將禁用命令。
- 按條件加載頁面組件的自定義服務器控件。
圖 4. 具有頁面組件的自定義組

|
為了便于閱讀,已略去示例代碼中的某些標記。有關完整代碼引用,請參閱 MSDN 示例 - 自定義和擴展 SharePoint 2010 Server 功能區(該鏈接可能指向英文頁面)。 |
如何:創建支持 Web 部件的上下文選項卡并利用回發
在本示例中,在將 Web 部件添加到頁面時,將顯示上下文選項卡,如之前的圖 3 所示。此選項卡包含提供幾個按鈕的兩個組。第一個組中的按鈕不執行任何操作,而只演示如何使用默認模板之一。但是,“Write to Web Part via PostBack”按鈕會發布一次回發。Web 部件包含用于檢查按鈕是否已發布回發的代碼,如果出現此情況,則向 Web 部件的內容中添加一些文本。
步驟 1:創建 Web 部件
第一個步驟是創建 Web 部件。使用新的 Microsoft Visual Studio 2010 中的 SharePoint 開發工具創建一個 SharePoint 項目,并向該項目中添加一個 Web 部件 SharePoint 項目項。CreateChildControls 方法執行兩個操作:將一些文本寫入 Web 部件,并在引發特定回發事件時調用方法以處理情況,如以下代碼中所示。
public class RibbonizedWebPart : WebPart { private string POSTBACK_EVENT = "RibbonizedWebPartPostback"; protected override void CreateChildControls() { this.Controls.Add( new LiteralControl( "<em>Ribbonized Web Part contents go here</em>" ) ); // Handle postback from ribbon. HandleRibbonPostback(); } }
接下來,創建處理回發事件的方法。如果它是一個特定的回發事件,則它會將其他一些文本寫入 Web 部件的內容,如以下代碼所示。
最后一步是,實現將向頁面中添加自定義上下文選項卡的代碼。可從 Web 部件的生命周期的 OnPreRender 階段實現這一點。它必須獲得對服務器功能區的引用,并確保已在頁面上加載腳本依賴項。最后,為了顯示上下文選項卡,它使 ID 為 Ribbon.PropertyChangerTab 的選項卡可用,并告知功能區在加載頁面時使 ID 為 Ribbon.WebPartContextualTabGroup 的上下文選項卡可用,如以下代碼所示。
protected override void OnPreRender(EventArgs e) { LoadAndActivateRibbonContextualTab(); base.OnPreRender(e); } private void LoadAndActivateRibbonContextualTab() { SPRibbon ribbon = SPRibbon.GetCurrent(this.Page); // Ensure ribbon exists. if (ribbon != null) { // Load dependencies if not already on the page. ScriptLink.RegisterScriptAfterUI(this.Page, "SP.Ribbon.js", false, true); // Load and activate contextual tab. ribbon.MakeTabAvailable("Ribbon.PropertyChangerTab"); ribbon.MakeContextualGroupInitiallyVisible( "Ribbon.WebPartContextualTabGroup", string.Empty); } }
步驟 2:創建服務器功能區組件自定義項
創建 Web 部件后,下一步是創建服務器功能區組件自定義項。為此,您創建一個上下文選項卡組,一個帶兩個組的選項卡和幾個控件。
Microsoft Visual Studio 2010 中的 SharePoint 開發工具不包含用于自定義功能區的 SharePoint 項目項模板。然而,通用的 SharePoint 項目項“空元素”可用于包含功能區自定義項,因此向項目中添加一個新的空元素。
步驟 2.1:向 Element 中添加核心功能區標記
在項目的新“Element”SharePoint 項目項中,向 element.xml 文件中添加以下標記。
這將告知 SharePoint 以下內容:
- 元素清單包含適用于任何位置的功能區 (
<CustomAction Location="CommandUI.Ribbon" />) 的功能區自定義項。有五個針對 Location 屬性的選項。開發人員可以通過其他選項指定,在顯示列表視圖 Web 部件時或者在某個項的顯示、新建或編輯表單上應顯示自定義項。另外,RegistrationType 和 RegistrationId 允許開發人員對自定義項的顯示位置進行更精確地定位。例如,開發人員可面向特定的內容類型。服務器功能區 XML 中列出了所有選項。
- 還包括功能區自定義項的基本結構。
步驟 2.2:添加新的上下文選項卡組
接下來,添加將創建上下文選項卡組的以下標記。
<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <CustomAction Id="WebPartContextualTabs" Location="CommandUI.Ribbon"> <CommandUIExtension> <CommandUIDefinitions> <CommandUIDefinition Location="Ribbon.ContextualTabs._children"> <ContextualGroup Id="Ribbon.WebPartContextualTabGroup" ContextualGroupId="WebPartContextualTab" Title="Ribbonized Web Part Tools" Sequence="150" Color="Green" Command="WebPartContextualTab.OnEnableContextualTab"> </ContextualGroup> </CommandUIDefinition> </CommandUIDefinitions> <CommandUIHandlers /> </CommandUIExtension> </CustomAction> </Elements>
<CommandUIDefinition> Location 屬性告知功能區向其中的上下文選項卡添加以下內容,即一個或多個 <ContextualGroup /> 元素。
<ContextualGroup /> 元素定義新組。它具有一個與上下文組的名稱匹配的 Id 屬性,Web 部件的代碼告知功能區在最初加載頁面時使該上下文組可見。
Sequence 屬性告知 SharePoint 此上下文組的順序(當存在其他上下文組時)。為 SharePoint 上下文組給定的序列將從 100 開始(即“編輯工具”上下文組),然后按 100 遞增。因此,如果存在“編輯工具”組,則上下文組可能會顯示在第一個或第二個位置。有關如何查找其他上下文組的名稱和序列的信息,請參見本文后面的自定義 SharePoint 2010 Server 功能區開發提示和技巧一節。
Command 屬性將此組與命令名稱關聯。在某些情況下,當選中此選項卡組時,運行腳本可能會很有用。但在此情況下,命令(稍后實現)用于告知功能區激活上下文組的時間。如果未實現,則一旦用戶單擊任何項,就會促使功能區隱藏自定義組。
步驟 2.3:向上下文選項卡組添加選項卡
在創建上下文選項卡組后,添加以下標記以添加新選項卡并定義最大大小布局組模板。
<CommandUIDefinitions> <CommandUIDefinition Location="Ribbon.ContextualTabs._children"> <ContextualGroup Id="Ribbon.WebPartContextualTabGroup" ... > <Tab Id="Ribbon.PropertyChangerTab" Title="Tools" Sequence="501"> <Scaling Id="Ribbon.PropertyChangerTab.Scaling"> <MaxSize Id="Ribbon.PropertyChangerTab.MaxSize" GroupId="Ribbon.PropertyChangerTab.PropertyGroup" Size="LargeLarge" /> <MaxSize Id="Ribbon.PropertyChangerTab.MaxSize" ... /> </Scaling> </Tab> </ContextualGroup> </CommandUIDefinition> </CommandUIDefinitions>
在圍繞 <MaxSize /> 元素的此代碼段中,需要注意兩點。它將稍后定義的組(通過 GroupId 屬性)與模板中定義的布局選項 LargeLarge(通過 Size 屬性)關聯。
步驟 2.4:向選項卡添加組
現在,通過添加以下標記向新選項卡添加組。
<CommandUIDefinitions> <CommandUIDefinition Location="Ribbon.ContextualTabs._children"> <ContextualGroup Id="Ribbon.WebPartContextualTabGroup" ... > <Tab Id="Ribbon.PropertyChangerTab" ... > <Scaling Id="Ribbon.PropertyChangerTab.Scaling" ... > </Scaling> <Groups Id="Ribbon.PropertyChangerTab.Groups"> <Group Id="Ribbon.PropertyChangerTab.PropertyGroup" ... > ... </Group> <Group Id="Ribbon.PropertyChangerTab.PostBackGroup" Title="PostBack" Sequence="25" Template="Ribbon.Templates.Flexible2"> </Group> </Groups> </Tab> </ContextualGroup> </CommandUIDefinition> </CommandUIDefinitions>
雖然本示例中有兩個組,但此代碼列表中僅顯示第二個組。請注意,組包含 Id 屬性,該屬性與之前已添加的 <MaxSize GroupId="" /> 元素匹配。
另請注意,組使用的是一個名為 Ribbon.Templates.Flexible2 的模板。該模板包含在內置 CMDUI.xml 功能區聲明中。在功能區自定義項功能中定義自定義組時,Microsoft 建議開發人員創建其自己的組模板,而不是使用提供的組模板之一。這樣做的原因是,SharePoint 不會為每個頁面請求加載整個功能區;而只加載當前上下文所需的部分功能區。這包括組模板。因此,如果開發人員依賴內置組模板,則可以不為當前頁面加載模板且不顯示其功能區自定義項。
對于此示例自定義項,由于這是 Web 部件的一部分,并且 Web 部件必須位于 Web 部件頁上,因此,假定將加載此模板,因為它是每個 Web 部件頁上都具有的“頁面”選項卡的一部分。
有關如何查找其他模板的名稱的信息,請參閱本文后面的自定義 SharePoint 2010 Server 功能區開發提示和技巧。
步驟 2.5:向組添加控件
定義功能區自定義項的可見部分的最后一個步驟是向組添加控件。將以下標記添加到第二個組(請參閱 MSDN 示例 - 自定義和擴展 SharePoint 2010 Server 功能區(該鏈接可能指向英文頁面),以將按鈕添加到第一個組)。
<CommandUIDefinitions> <CommandUIDefinition Location="Ribbon.ContextualTabs._children"> <ContextualGroup Id="Ribbon.WebPartContextualTabGroup" ... > <Tab Id="Ribbon.PropertyChangerTab" ... > <Scaling Id="Ribbon.PropertyChangerTab.Scaling" ... > </Scaling> <Groups Id="Ribbon.PropertyChangerTab.Groups"> <Group Id="Ribbon.PropertyChangerTab.PropertyGroup" ... > ... </Group> <Group Id="Ribbon.PropertyChangerTab.PostBackGroup" ... > <Controls Id="Ribbon.PropertyChangerTab.PropertyGroup.Controls"> <Button Id="Ribbon.PropertyChangerTab.PropertyGroup.GeneralDialogButton" LabelText="Write to Web Part" Command="WebPartContextualTabs.OnPostback" TemplateAlias="o1" Sequence="15" Image16by16="/_layouts/Images/WebPartRibbonContextualTab/16x16Placeholder.png" Image32by32="/_layouts/Images/WebPartRibbonContextualTab/32x32Placeholder.png" /> </Controls> </Group> </Groups> </Tab> </ContextualGroup> </CommandUIDefinition> </CommandUIDefinitions>
此標記將向具有寫入 Web 部件的標簽的組中添加一個新按鈕控件。在單擊此按鈕時,它將觸發 Command=""。TemplateAlias 屬性告知服務器功能區定義的組模板將按鈕放置到的位置。最后,布局將使用兩個圖像屬性來顯示處于不同狀態的功能區圖標。這些圖像可指向服務器上的任何圖像。在此示例中,它們指向已添加到項目中的圖像。
步驟 3:創建服務器功能區命令
最后一個步驟是,定義已在功能區組件中引用的兩個命令。將以下標記添加到元素清單。
<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <CustomAction Id="WebPartContextualTabs" Location="CommandUI.Ribbon"> <CommandUIExtension> <CommandUIDefinitions> ... </CommandUIDefinitions> <CommandUIHandlers> <CommandUIHandler Command="WebPartContextualTab.OnEnableContextualTab" CommandAction="" EnabledScript="return true;" /> <CommandUIHandler Command="WebPartContextualTabs.OnPostback" CommandAction="javascript:__doPostBack('RibbonizedWebPartPostback','');" /> </CommandUIHandlers> </CommandUIExtension> </CustomAction> </Elements>
第一個 <CommandUIHandler /> 具有一個與上下文選項卡組關聯的命令。如前所述,此命令僅用來告知 Server 功能區其激活時間,而不執行任何其他操作。為了在功能區中不顯示此命令,其 EnabledScript 屬性將始終返回 TRUE。因此,如果上下文選項卡組位于頁面上(此時 Web 部件也位于頁面上,因為 Web 部件將處理其激活),則它決不會消失。
第二個 <CommandUIHandler /> 與按鈕控件關聯。當單擊該控件時,將觸發一個包含名為 RibbonizedWebPartPostBack 的事件的回發?;叵胍幌?,Web 部件中的代碼正在偵聽該事件名稱,并在發現該名稱時向 Web 部件中添加文本。
步驟 4:部署和測試
在保存所有更改后,通過在 Visual Studio 2010 中按 F5,或通過在“調試”菜單上單擊“開始調試”來部署自定義 Web 部件。
在加載初始網頁時,您會發現未顯示上下文選項卡,如圖 5 所示。
圖 5. 不具有上下文選項卡組的調試網站的主頁

現在,通過選擇“頁面”選項卡,然后單擊“編輯”,可將頁面置于編輯模式中。將頁面上的 Web 部件插入默認位置。在重新加載頁面時,您會發現,上下文選項卡和 Web 部件都是可見的,如圖 6 所示。
圖 6. 上下文選項卡和 Web 部件是可見的

通過選擇自定義上下文選項卡組中的“工具”選項卡,然后單擊相應的按鈕來測試回發。頁面應被刷新并在 Web 部件中包含其他文本,如圖 7 所示。
圖 7. 響應來自功能區的回發的 Web 部件

還請注意,上下文選項卡組將作為第二個上下文選項卡組顯示在頁面上。這是因為,頁面仍處于編輯模式中,并且序列已設置為 150(大于編輯工具序列)。在頁面退出編輯模式后,自定義上下文組應顯示在第一個位置。
演練:向文檔選項卡中添加按鈕并有條件地啟用它們
本演練中的示例演示如何將帶按鈕的新組添加到現有功能區。在部署項目時,它會在“文檔”選項卡中注冊一個新組,該組是“庫工具”上下文選項卡組的一部分。此上下文選項卡組僅在用戶與文檔交互或位于文檔庫中時顯示。圖 8 演示了不帶功能區的工作組網站主頁,但在選中共享文檔庫時(如圖 9 所示),顯示的上下文選項卡組會帶自定義項。
圖 8. 未選定文檔庫的工作組網站主頁

圖 9. 已選定文檔庫的工作組網站主頁

最初,三個按鈕中有兩個按鈕未啟用。除非選定一個或多個文檔,否則將啟用與按鈕關聯的命令,如圖 10 所示。
圖 10. 在選定文檔時啟用的功能區按鈕

在單擊后面兩個按鈕(即“Apply Prefix w/ CommandUI Handler”和“Apply Prefix w/ Page Component”)時,將執行相同的操作。但從其名稱可了解,一個按鈕將使用命令 UI 處理程序,而另一個按鈕將使用自定義頁面組件。在單擊按鈕時,它們會收集頁面上所有選定文檔的列表,并將這些文檔傳遞給一個新對話框,如圖 11 所示。此對話框允許用戶向所有選定文檔的名稱添加前綴。
圖 11. 從功能區自定義項引發的自定義對話框

在單擊“Set Prefix”按鈕時,對話框將更新所有文檔的名稱,然后關閉。根據對話框是通過單擊“Set Prefix”按鈕還是通過單擊“Cancel”來關閉的,命令會發出一條通知消息,然后刷新頁面上的列表視圖 Web 部件,以更新列表內容。
步驟 1:創建服務器功能區組件自定義項
第一步是,使用 Microsoft Visual Studio 2010 中的 SharePoint 開發工具創建一個新的 SharePoint 空項目。在創建該項目時,向該項目中添加一個將包含功能區自定義項的新的“空元素”項目項。
步驟 1.1:向 Element 中添加核心功能區標記
在元素清單內添加以下標記。
<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <CustomAction Id="Ribbon.Documents.ApplyDocumentPrefix" Location="CommandUI.Ribbon"> <CommandUIExtension> <CommandUIDefinitions> <CommandUIDefinition Location="Ribbon.Documents.Groups._children"> <Group Id="Ribbon.Documents.ApplyDocumentPrefix" Title="Document Naming Tools" Description="Document Naming Tools Description" Sequence="25" Template="Ribbon.Templates.MsdnTemplate"> </Group> </CommandUIDefinition> </CommandUIDefinitions> <CommandUIHandlers /> </CommandUIExtension> </CustomAction> </Elements>
這將向“文檔”選項卡的一個名為“Document Naming Tools”的組集合中添加一個新組,如 <CommandUIDefinition Location="Ribbon.Documents.Groups._children"> 所示。該組包含一個由 25 個項組成的序列。內置 SharePoint 2010 服務器功能區中的組的編號從數字 10 開始按 10 遞增。這意味著,此處定義的自定義組將在第三個位置顯示。
另外,該組將不會使用某個現有組模板,而將使用一個自定義組模板。
步驟 1.2:添加自定義組模板
添加以下標記以向功能區添加自定義組。
<CommandUIExtension> <CommandUIDefinitions> <CommandUIDefinition Location="Ribbon.Documents.Groups._children"> <Group Id="Ribbon.Documents.ApplyDocumentPrefix" ... > ... </Group> </CommandUIDefinition> <CommandUIDefinition Location="Ribbon.Templates._children"> <GroupTemplate Id="Ribbon.Templates.MsdnTemplate"> <Layout Title="MsdnHorizontal"> <Section Type="OneRow"> <Row> <ControlRef DisplayMode="Large" TemplateAlias="o1" /> <ControlRef DisplayMode="Large" TemplateAlias="o2" /> <ControlRef DisplayMode="Large" TemplateAlias="o3" /> </Row> </Section> </Layout> <Layout Title="MsdnVertical"> <Section Type="ThreeRow"> <Row><ControlRef DisplayMode="Medium" TemplateAlias="o1" /></Row> <Row><ControlRef DisplayMode="Medium" TemplateAlias="o2" /></Row> <Row><ControlRef DisplayMode="Medium" TemplateAlias="o3" /></Row> </Section> </Layout> <Layout Title="MsdnVerticalTextOnly"> <Section Type="ThreeRow"> <Row><ControlRef DisplayMode="Menu" TemplateAlias="o1" /></Row> <Row><ControlRef DisplayMode="Menu" TemplateAlias="o2" /></Row> <Row><ControlRef DisplayMode="Menu" TemplateAlias="o3" /></Row> </Section> </Layout> </GroupTemplate> </CommandUIDefinition> <CommandUIDefinitions> <CommandUIHandlers /> </CommandUIExtension>
此模板(即“Ribbon.Templates.MsdnTemplate”)包含三個不同的布局。每個 <Layout /> 具有一個 Title 屬性,<MaxSize /> 元素或 <Scale /> 元素中引用了該屬性。這會告知功能區要用于布局的模板。每個 <Layout /> 元素均具有一個 <Section />,它使用 Type 屬性定義組的呈現方式。這可以是 4 個用于呈現組的選項之一,這些選項包括使用一行、使用兩行、使用三行或使用分隔線。有關詳細信息,請參閱 Section 元素。
<Section /> 包含一個或多個 <Row /> 元素,這些元素定義布局中的每個行。<Row /> 元素包含充當控件的占位符的 <ControlRef /> 元素。DisplayMode 屬性告知功能區如何使用文本標簽、大圖標、小圖標或 ControlRef 元素的架構中定義的其他選項之一來呈現控件。TemplateAlias 屬性用于觸發特定控件放置。在向組添加控件時,每個控件的 TemplateAlias 屬性將與這些 TemplateAlias 屬性之一匹配以準確指定控件的放置位置。
現在添加以下標記,以告知功能區如何通過使用已定義模板中的布局之一來呈現組。
<CommandUIExtension> <CommandUIDefinitions> <CommandUIDefinition Location="Ribbon.Documents.Groups._children"> <Group Id="Ribbon.Documents.ApplyDocumentPrefix" ... > ... </Group> </CommandUIDefinition> <CommandUIDefinition Location="Ribbon.Documents.Scaling._children"> <MaxSize Id="Ribbon.Documents.Scaling.ApplyDocumentPrefix.MaxSize" GroupId="Ribbon.Documents.ApplyDocumentPrefix" Size="MsdnVertical" Sequence="15" /> </CommandUIDefinition> <CommandUIDefinition Location="Ribbon.Templates._children"> <GroupTemplate Id="Ribbon.Templates.MsdnTemplate"> ... </GroupTemplate> </CommandUIDefinition> </CommandUIDefinitions> <CommandUIHandlers /> </CommandUIExtension>
圖 12、13 和 14 演示如何僅通過將 <MaxSize Size="" /> 屬性更改為不同的布局選項來更改組的呈現。
圖 12. 使用 MsdnHorizontal 布局

圖 13. 使用 MsdnVertical 布局

圖 14. 使用 MsdnVerticalTextOnly 布局

步驟 1.3:向功能區組添加控件
接下來,向元素清單文件添加以下標記,以向組中添加幾個按鈕。
<CommandUIExtension> <CommandUIDefinitions> <CommandUIDefinition Location="Ribbon.Documents.Groups._children"> <Group Id="Ribbon.Documents.ApplyDocumentPrefix" ... > <Controls Id="Ribbon.Documents.ApplyDocumentPrefix.Controls"> <Button Id="Ribbon.Documents.ApplyDocumentPrefix.CustomHelpButton" LabelText="Apply Document Prefix Help" TemplateAlias="o1" Sequence="15" Image16by16="/_layouts/Images/ApplyDocumentPrefixRibbon/16x16Placeholder.png" Image32by32="/_layouts/Images/ApplyDocumentPrefixRibbon/32x32Placeholder.png" Command="ApplyDocumentPrefix.OnGetHelpApplyDocPrefix" /> <Button Id="Ribbon.Documents.ApplyDocumentPrefix.CustomApplyPrefixButton" LabelText="Apply Prefix w/ CommandUI Handler" TemplateAlias="o2" Sequence="17" Image16by16="/_layouts/Images/ApplyDocumentPrefixRibbon/16x16Placeholder.png" Image32by32="/_layouts/Images/ApplyDocumentPrefixRibbon/32x32Placeholder.png" Command="ApplyDocumentPrefix.OnApplyDocPrefixUIHandler" /> <Button Id="Ribbon.Documents.ApplyDocumentPrefix.CustomPageComponentButton" LabelText="Apply Prefix w/ Page Component" TemplateAlias="o3" Sequence="19" Image16by16="/_layouts/Images/ApplyDocumentPrefixRibbon/16x16Placeholder.png" Image32by32="/_layouts/Images/ApplyDocumentPrefixRibbon/32x32Placeholder.png" Command="ApplyDocumentPrefix.OnApplyDocPrefixPageComponent" /> </Controls> </Group> </CommandUIDefinition> </CommandUIDefinitions> <CommandUIHandlers /> </CommandUIExtension>
請注意,每個按鈕都會連接到其自己的命令。在完成功能區自定義項的可見部分后,緊接著是創建用于處理按鈕的可用時間以及按鈕被單擊時執行的操作的命令。通過使用命令 UI 處理程序或頁面組件可完成此操作。后面的兩個步驟將演示如何實現這兩點。
步驟 2:創建服務器功能區命令 UI 處理程序
在包含功能區可見自定義項的同一元素清單文件中定義命令 UI 處理程序。添加以下標記以創建首個命令 UI 處理程序。
<CommandUIHandlers> <CommandUIHandler Command="ApplyDocumentPrefix.OnGetHelpApplyDocPrefix" CommandAction="javascript: var dialogOptions = { url: '/_layouts/ApplyDocumentPrefixRibbon/DocPrefixHelp.aspx', title: 'Apply Document Prefix Help', allowMaximize: true, showClose: true, width:500, height:400 }; SP.UI.ModalDialog.showModalDialog(dialogOptions); " /> </CommandUIHandlers>
通過使用 Command 屬性將此命令連接到第一個按鈕。CommandAction 屬性會執行一些 ECMAScript,這將使用指向一個稍后將創建的自定義應用程序頁的 SharePoint 2010 對話框框架來打開一個對話框。
添加將與第二個按鈕關聯的另一個命令 UI 處理程序。此處理程序執行了大量工作,如以下標記所示。
<CommandUIHandlers> <CommandUIHandler Command="ApplyDocumentPrefix.OnGetHelpApplyDocPrefix" ... /> <CommandUIHandler Command="ApplyDocumentPrefix.OnApplyDocPrefixUIHandler" CommandAction="javascript: function dialogCallback(dialogResult, returnValue){ SP.UI.Notify.addNotification(returnValue); SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK); } var selectedItems = SP.ListOperation.Selection.getSelectedItems(); var selectedItemIds = ''; var selectedItemIndex; for (selectedItemIndex in selectedItems){ selectedItemIds += '|' + selectedItems[selectedItemIndex].id; } var dialogOptions = { url: '/_layouts/ApplyDocumentPrefixRibbon/DocPrefixPrompt.aspx?selectedItems=' +selectedItemIds +'&ListId=' +SP.ListOperation.Selection.getSelectedList(), title: 'Set Document Prefix', allowMaximize: false, showClose: false, width:500, height:400, dialogReturnValueCallback: dialogCallback }; SP.UI.ModalDialog.showModalDialog(dialogOptions);" EnabledScript="javascript: function checkIsEnabled(){ // Check items selected. var selectedItems = SP.ListOperation.Selection.getSelectedItems(); var count = CountDictionary(selectedItems); return (count > 0); }; checkIsEnabled();" /> </CommandUIHandlers>
此處理程序更為復雜一些。首先,它創建一個新的 ECMAScript 函數,此函數在關閉對話框時將用作回調。它在瀏覽器中顯示一個通知(從頁面右側滑入的用黃色顯示的消息),然后刷新頁面上的列表視圖 Web 部件。
然后,它創建一個在當前頁面上選定的文檔的分隔列表。最后,它創建一個新對話框,該對話框將打開一個新的應用程序頁并傳入選定項。當對話框關閉時,它將調用前面定義的 dialogCallback 方法。
它的另一個重要部分是 EnabledScript 屬性。如果命令可用,則此屬性返回的布爾值為 TRUE;如果命令不可用,則返回 FALSE。為了確定這一點,它將檢查是否已在頁面上選定其他選項。如果未選定,則將禁用命令和此按鈕。
步驟 3:創建服務器功能區頁面組件
在功能區中具有一個使用在命令 UI 處理程序中定義的命令的按鈕之后,現在可以創建頁面組件來處理其他命令。通過將新的 ECMAScript 文件添加到 Visual Studio 項目(最好是添加到已映射到 {SharePoint Root}/TEMPLATE/LAYOUT/{ProjectName} 目錄的文件夾中)來實現這一點。這將確保供所有網站使用的前端 Web 服務器上只有一個庫實例。
步驟 3.1:聲明頁面組件對象
在將文件添加到項目后,將以下腳本添加到庫以聲明此庫將包含的 ECMAScript 對象,以及少量構造函數和初始化方法,它們將創建一個頁面組件實例并將該實例添加到客戶端功能區管理器。以下標記對此進行了演示。
// Register the page component object. Type.registerNamespace('ApplyDocumentPrefix'); // Helper methods to set up and initialize the page component. ApplyDocumentPrefix.ApplyDocumentPrefixPageComponent = function ApplyDocumentPrefix_PageComponent() { ApplyDocumentPrefix.ApplyDocumentPrefixPageComponent.initializeBase(this); } ApplyDocumentPrefix.ApplyDocumentPrefixPageComponent.initialize = function () { ExecuteOrDelayUntilScriptLoaded(Function.createDelegate(null, ApplyDocumentPrefix.ApplyDocumentPrefixPageComponent.initializePageComponent), 'SP.Ribbon.js'); } ApplyDocumentPrefix.ApplyDocumentPrefixPageComponent.initializePageComponent = function () { var ribbonPageManager = SP.Ribbon.PageManager.get_instance(); if (ribbonPageManager !== null) { ribbonPageManager.addPageComponent(ApplyDocumentPrefix.ApplyDocumentPrefixPageComponent.instance); } }
步驟 3.2:創建頁面組件對象原型和 init 方法
現在,為對象原型和核心 init 方法添加以下腳本。從其名稱可以了解,此方法將通過創建幾個數組來初始化對象,這些數組會列出命令并將命令映射到對象內的特定函數。
// Page component object. ApplyDocumentPrefix.ApplyDocumentPrefixPageComponent.prototype = { init: function ApplyDocumentPrefix_PageComponento$init() { // Array of commands that can be handled that are associated with handler methods. this.handledCommands = new Object; this.handledCommands['ApplyDocumentPrefix.OnApplyDocPrefixPageComponent'] = this.onApplyDocPrefixPageComponent; // Array of commands that can be handled that are associated with canHandler methods. this.canHandledCommands = new Object; this.canHandledCommands['ApplyDocumentPrefix.OnApplyDocPrefixPageComponent'] = this.onApplyDocPrefixPageComponent_canExecute; // Array of commands. this.commandList = ['ApplyDocumentPrefix.OnApplyDocPrefixPageComponent']; }, getId: function ApplyDocumentPrefixPageComponent_PageComponent$getId() { return "ApplyDocumentPrefixPageComponent"; }, ... }
請注意,在定義功能區自定義項的可見組件時,數組中命令的名稱與前面添加的 <Button Command="" /> 屬性的值匹配。
步驟 3.3:添加方法以告知功能區管理器此頁面組件處理的命令以及處理命令的方式和時間
接下來,添加四個方法,這四個方法告知客戶端功能區管理器哪些命令可用以及處理這些命令的方式和時間,如以下代碼所示。
ApplyDocumentPrefix.ApplyDocumentPrefixPageComponent.prototype = {
...
getFocusedCommands: function ApplyDocumentPrefixPageComponent_PageComponent$getFocusedCommands() {
return [];
},
getGlobalCommands: function ApplyDocumentPrefixPageComponent_PageComponent$getGlobalCommands() {
return this.commandList;
},
canHandleCommand: function
ApplyDocumentPrefixPageComponent_PageComponent$canHandleCommand(commandID) {
var canHandle = this.handledCommands[commandID];
if (canHandle)
return this.canHandledCommands[commandID]();
else
return false;
},
handleCommand: function
ApplyDocumentPrefixPageComponent_PageComponent$handleCommand(commandID,
properties, sequence) {
return this.handledCommands[commandID](commandID, properties, sequence);
},
...
}
canHandleCommand 方法與命令 UI 處理程序的 EnabledScript 屬性的功能相同,這些屬性告知功能區管理器命令是否可用。在上一個代碼段中,該方法使用在對象的初始值設定項中創建的數組來調用對象中的特定方法。handleCommand 的功能與命令 UI 處理程序的 CommandAction 屬性的功能相似。它也使用一個數組以指向指定命令的另一個方法。
步驟 3.4:添加特定命令方法
接下來是,添加已在對象的初始值設定項中定義且被調用的方法,以確定命令何時可用 (onApplyDocPrefixPageComponent_canExecute) 以及執行命令時發生的操作 (onApplyDocPrefixPageComponent)。
ApplyDocumentPrefix.ApplyDocumentPrefixPageComponent.prototype = {
...
onApplyDocPrefixPageComponent: function () {
var selectedItems = SP.ListOperation.Selection.getSelectedItems();
var selectedItemIds = '';
var selectedItemIndex;
for (selectedItemIndex in selectedItems) {
selectedItemIds += '|' + selectedItems[selectedItemIndex].id;
}
var dialogOptions = {
url: '/_layouts/ApplyDocumentPrefixRibbon/DocPrefixPrompt.aspx?selectedItems=' +
selectedItemIds + '&ListId=' + SP.ListOperation.Selection.getSelectedList(),
title: 'Set Document Prefix',
allowMaximize: false,
showClose: false,
width: 500,
height: 400,
dialogReturnValueCallback: PageComponentCallback
};
SP.UI.ModalDialog.showModalDialog(dialogOptions);
},
onApplyDocPrefixPageComponent_canExecute: function () {
var selectedItems = SP.ListOperation.Selection.getSelectedItems();
var count = CountDictionary(selectedItems);
return (count > 0);
}
...
}
function PageComponentCallback(dialogResult, returnValue) {
SP.UI.Notify.addNotification(returnValue);
SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
}
步驟 3.5:添加最后對象注冊、初始化和通知腳本
完成頁面組件對象之后,最后的步驟是:在頁面上注冊該對象;創建該對象;通知客戶端功能區,正在等待此腳本完成該對象加載的任何操作已完成加載和初始化。這些步驟如以下代碼所示。
ApplyDocumentPrefix.ApplyDocumentPrefixPageComponent.prototype = {
...
}
ApplyDocumentPrefix.ApplyDocumentPrefixPageComponent.registerClass
('ApplyDocumentPrefix.ApplyDocumentPrefixPageComponent',
CUI.Page.PageComponent);
ApplyDocumentPrefix.ApplyDocumentPrefixPageComponent.instance =
new ApplyDocumentPrefix.ApplyDocumentPrefixPageComponent();
ApplyDocumentPrefix.ApplyDocumentPrefixPageComponent.initialize();
SP.SOD.notifyScriptLoadedAndExecuteWaitingJobs("ApplyDocumentPrefix.UI.js");
此時,已創建頁面組件,并且現在可將該組件添加到頁面。
步驟 4:創建服務器功能區頁面組件加載程序
接下來,必須將頁面組件添加到頁面。在此示例中,自定義服務器控件用于執行此操作。向項目中添加一個新的 Empty Element SharePoint 項目項。使用 <Control /> 元素以注冊一個具有以下標記的新委托控件。
這會將服務器控件 PageComponentScriptLoader 添加到當前網站中所有頁面的 AdditionalPageHead 內容占位符中(不管功能的范圍如何)?,F在,向 SharePoint 項目項中添加一個新的代碼文件,并添加以下代碼以實現服務器控件。
public class PageComponentScriptLoader : WebControl { protected override void OnPreRender(EventArgs e) { SPRibbon ribbon = SPRibbon.GetCurrent(this.Page); // Ensure ribbon exists and current list is a document library // (otherwise, no need for extra ecmascript load). if (ribbon != null && SPContext.Current.List is SPDocumentLibrary) { // Load dependencies if not already on the page. ScriptLink.RegisterScriptAfterUI(this.Page, "SP.Ribbon.js", false, true); // Load page component. . ScriptLink.RegisterScriptAfterUI(this.Page, "ApplyDocumentPrefixRibbon/ApplyDocumentPrefix.UI.js", false, true); } base.OnPreRender(e); } }
這將首先獲取對服務器功能區的引用。當用戶使用文檔庫時,它將首先驗證頁面上的從屬腳本,然后再注冊頁面組件。
此處的最后一個步驟是,將 <SafeControl /> 項添加到網站的 web.config 文件。雖然“空元素”SharePoint 項目項不自動添加 <SafeControl /> 項,但它為我們提供了執行此操作的方法。在 Visual Studio 2010 中的“解決方案資源管理器”中,選擇“空元素”。在“屬性”窗口中,單擊“[…]”生成器按鈕,如圖 15 所示。
圖 15. 使用 Visual Studio 2010 中的 SharePoint 開發工具手動添加安全控制項

在“安全控制項”對話框中,添加一個新項,然后驗證命名空間是否與先前創建的服務器控件的命名空間匹配。
圖 16.“安全控制項”對話框

步驟 5:創建自定義對話框
最后一個步驟是,創建由自定義功能區命令調用的且執行大部分工作的對話框。將一個新的“應用程序頁”SharePoint 項目項添加到 Visual Studio 項目。
步驟 5.1:實現對話框的可見部分 (.aspx)
在此示例中,對話框使用了幾個 SharePoint 管理表單用戶控件,因此需要一些引用,如以下代碼所示。
<%@ Register TagPrefix="wssuc" TagName="InputFormSection" Src="~/_controltemplates/InputFormSection.ascx" %> <%@ Register TagPrefix="wssuc" TagName="InputFormControl" src="~/_controltemplates/InputFormControl.ascx" %> <%@ Register TagPrefix="wssuc" TagName="ButtonSection" Src="~/_controltemplates/ButtonSection.ascx" %>
在 PlaceHolderMain 內容占位符中,添加以下標記以創建帶 ASP.NET DataList 控件的表單,該控件將顯示所有選定文檔的列表。
<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td>
<wssuc:InputFormSection runat="server"
Title="Selected Documents"
Description="The following documents have been selected
to have the specified prefix added to their titles.">
<Template_InputFormControls>
<tr>
<td>
<asp:DataList ID="SelectedDocumentsDataList" runat="server"
RepeatColumns="2" CellPadding="2" CellSpacing="5">
<ItemTemplate><li><%# DataBinder.Eval(Container.DataItem,
"File.Name").ToString()%></li></ItemTemplate>
</asp:DataList>
</td>
</tr>
</Template_InputFormControls>
</wssuc:InputFormSection>
<wssuc:InputFormSection runat="server"
Title="Document Prefix"
Description="Prefix to add to the selected document
titles.">
<Template_InputFormControls>
<wssuc:InputFormControl LabelText="Prefix to add to the selected documents:"
runat="server">
<Template_control>
<asp:TextBox ID="DocumentPrefixTextBox" runat="server" />
</Template_control>
</wssuc:InputFormControl>
</Template_InputFormControls>
</wssuc:InputFormSection>
<wssuc:ButtonSection runat="server" ShowStandardCancelButton="FALSE"
TopButtons="TRUE">
<Template_Buttons>
<asp:Button ID="SetPrefixButton" class="ms-ButtonHeightWidth" runat="server"
Text="Set Prefix" OnClick="OnClickSetPrefixButton" />
<asp:Button ID="CancelButton" class="ms-ButtonHeightWidth" runat="server"
Text="Cancel" OnClientClick=
"SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.cancel,
'Assignment of prefix cancelled.'); return false;" />
</Template_Buttons>
</wssuc:ButtonSection>
</td>
</tr>
</table>
</asp:Content>
步驟 5.2:實現代碼隱藏中的業務邏輯 (.aspx.cs)
此應用程序頁的代碼隱藏非常簡單。它需要執行以下任務:
- 獲取在 QueryString 上傳入的所有選定文檔的列表。
- 獲取對包含在 QueryString 上傳入的文檔的列表的引用。
- 顯示通過將選定文檔的集合綁定到 ASP.NET DataList
控件來選定的項。
- 單擊時,將更新所有選定項的文件名。
- 完成后,將一些 ECMAScript 寫入將關閉對話框的
PlaceHolderAdditionalPageHead
內容占位符,這會將結果發送回調用頁面。
向應用程序頁的代碼隱藏文件中添加以下代碼。
public partial class DocPrefixPrompt : LayoutsPageBase { List<SPListItem> _selectedListItems = new List<SPListItem>(); protected override void OnLoad(EventArgs e) { // Get all the selected documents. SPList selectedDocumentLibrary = SPContext.Current.Web.Lists[new Guid( Request.QueryString["ListId"] )]; string[] selectedItems = Request.QueryString["selectedItems"].ToString().Split('|'); for (int index = 1; index < selectedItems.Length; index++) { _selectedListItems.Add( selectedDocumentLibrary.GetItemById( int.Parse(selectedItems[index])) ); } // Bind to the repeater. SelectedDocumentsDataList.DataSource = _selectedListItems; SelectedDocumentsDataList.DataBind(); } protected void OnClickSetPrefixButton(object sender, EventArgs e) { foreach (SPListItem listItem in _selectedListItems) { listItem["Name"] = DocumentPrefixTextBox.Text + " " + listItem.File.Name; listItem.Update(); } CloseDialogOnSuccess(); } private void CloseDialogOnSuccess() { ContentPlaceHolder pageHead = this.Master.FindControl("PlaceHolderAdditionalPageHead") as ContentPlaceHolder; if (pageHead != null) pageHead.Controls.Add( new LiteralControl(" <script language='javascript'> ExecuteOrDelayUntilScriptLoaded(closeDialog,'sp.js'); function closeDialog(){ SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK, 'Prefix assigned to selected documents.'); } </script>")); } }
步驟 6:部署和測試自定義 Web 部件
在保存所有更改后,通過在 Visual Studio 2010 中按 F5,或通過在“調試”菜單上單擊“開始調試”來部署自定義 Web 部件。
在打開工作組網站的初始網頁時,單擊“共享文檔庫”。通過選擇功能區上的“文檔”選項卡可使功能區自定義項可見,如圖 9 所示。在選定某個文檔后,將啟用自定義組中的所有按鈕,如圖 10 所示。單擊兩個“Apply Prefix […]”按鈕之一將觸發對話框,如圖 11 所示。
當用戶單擊“Set Prefix”按鈕時,該對話框將更新選定的文件名,然后關閉。之后,命令將發出一條表明已應用更改的通知消息,并刷新列表視圖 Web 部件。
自定義 SharePoint 2010 Server 功能區開發提示和技巧
在自定義 SharePoint 2010 服務器功能區時,開發人員可以進行各種更改。提供了各種可用控件、可重用的模板以及可進行修改或添加操作的組和選項卡。幸運的是,大多數功能區是以聲明方式構造的,或(對于頁面組件)駐留在比已編譯代碼更易讀取的腳本文件中。這意味著,在安裝 SharePoint 后,開發人員將擁有大量可用的代碼示例。
技巧在于了解這些示例的查找位置和查找方式??稍谌志W站定義的 {SharePoint Root}\TEMPLATE\GLOBAL\XML\CMDUI.XML 文件中找到基服務器功能區和所有功能區聲明。通常,可以在各種功能中找到由 SharePoint Server 2010 企業內容管理等項進行的其他更改。只需在所有 *.xml 文件中搜索 <CommandUIExtension> 元素,就將顯示包含功能區擴展的所有功能的列表。
以下各節針對自定義功能區的一些常見情況,幫助開發人員找到正確的方向。
查找選項卡、組以及控件名稱和序列
創建新選項卡、將組添加到選項卡或修改現有控件是一項常見任務。第一個步驟是查找選項卡的 ID 或名稱。SharePoint 2010 SDK 包含所有選項卡及其位置的列表。有關詳細信息,請參閱默認服務器功能區自定義位置。由于選項卡名稱的描述很清晰,因此很容易了解哪個選項卡對應哪個名稱。此頁還包含所有組及其控件的名稱的列表。僅缺少序列和模板別名。
若要查找序列和模板別名,請打開 CMDUI.xml 文件并搜索相關選項卡、組或 SDK 中列出的控件 ID。這樣,您將獲得可回答有關控件的任何問題的相關項。
始終獲取清除頁面請求:清除瀏覽器緩存
在自定義功能區時,開發人員肯定會編寫 ECMAScript 并引用圖像。ECMAScript 和圖像及功能區自定義項的數量取決于應用程序的復雜度。
在重構 SharePoint 2010 UI 并開發功能區時,Microsoft 會側重于盡可能地限制頁面的權重或頁面上所需的所有內容的組合大小。為此,SharePoint 會主動在瀏覽器中緩存 CSS 文件和 ECMAScript 庫。這反過來為用戶提供了更短的頁面加載時間,因為后續請求上請求的文件更少。
雖然這為用戶帶來了好處,但同時也為開發人員帶來了挑戰。由于瀏覽器未下載最新的腳本或自定義項,因此無法顯示在正在調試的會話間所做的更改。在部署解決方案后等待加載解決方案時的最佳做法是,使用 Internet Explorer 開發人員工具欄。
圖 17. 清除 IE 緩存并強制下載所有文件

Internet Explorer 開發人員工具欄還提供了瀏覽腳本文件的方法。若要驗證瀏覽器是否下載了最新版本的自定義腳本文件,請使用“腳本”選項卡,并選擇已由頁面加載的腳本文件。如果未列出外部腳本文件,則不會將其添加到頁面。圖 18 演示了從上一個示例中選擇頁面組件外部腳本庫并查看其內容。
圖 18. 使用 IE 開發人員工具欄進行的腳本調試

結論
本文說明了構成 Microsoft SharePoint 2010 服務器功能區的核心組件。然后,向您演示如何創建使用不同的自定義技術的兩個示例功能區更改。另外,本文還提供有關何時考慮不同的命令實現選項(命令 UI 處理程序或頁面組件)的指南,并提供了有關功能區自定義項開發的提示和技巧。
浙公網安備 33010602011771號