暢談Visual Studio 2010中的SharePoint插件
Visual Studio 2010***的賣點(diǎn)就是可擴(kuò)展性。這樣就可以借助.NET社區(qū)的力量基于VS構(gòu)建出許多有用的工具。本文中我們將展示如何擴(kuò)展VS2010的服務(wù)器資源管理器,在其中的SharePoint結(jié)點(diǎn)上添加一個(gè)自定義操作。
SharePoint服務(wù)器資源管理器是Visual Studio 2010的一項(xiàng)新特性,該功能是由Visual Studio Tools for SharePoint提供的。
如果你只需要從Visual Studio中瀏覽SharePoint站點(diǎn)里的內(nèi)容(網(wǎng)站欄,內(nèi)容類型,功能等),那么默認(rèn)功能對(duì)你來(lái)說(shuō)就已經(jīng)非常好用了。 然而,在默認(rèn)情況下,SharePoint服務(wù)器資源管理器除了可以顯示網(wǎng)站里有哪些可用的內(nèi)容以外,其它什么也做不了。
正如你所看到的,上下文菜單中僅有很少的幾項(xiàng)。下圖是通知列表的屬性面板。 該屬性存儲(chǔ)在Annotations中。為了方便理解什么是Annotation,你可以把它們想象成一個(gè)帶屬性的類。這些屬性就是我們?cè)谙旅娴膶傩悦姘逯锌吹降模?/p>
這里還是只讀的。
我可以擴(kuò)展嗎?
接下來(lái)你一定會(huì)問(wèn)這樣一個(gè)問(wèn)題(如果你是一名SharePoint開發(fā)人員的話)——我能不能對(duì)其進(jìn)行擴(kuò)展,向SharePoint服務(wù)器資源管理器中添加自定義的命令或結(jié)點(diǎn)呢?
答案是肯定的。你可以擴(kuò)展SharePoint服務(wù)器資源管理器,包括:
1)創(chuàng)建新結(jié)點(diǎn)
2)擴(kuò)展已有結(jié)點(diǎn)
給我個(gè)例子好嗎?
讓我們以功能結(jié)點(diǎn)為例。
功能結(jié)點(diǎn)下顯示了該網(wǎng)站下所有已激活的功能。如果右擊某個(gè)功能,你會(huì)看到少得可憐的幾項(xiàng)。
如果能在上下文菜單中添加一項(xiàng)“停用”,點(diǎn)擊可以停用選中的功能,那就太帥了:)
[順帶說(shuō)一句,這張截圖是實(shí)實(shí)在在的做好的擴(kuò)展,而非Photoshop出來(lái)的:)]
理解SharePoint服務(wù)器資源管理器
在正式開始編寫一個(gè)擴(kuò)展之前,你必須了解一下SharePoint服務(wù)器資源滾利器中不同類型的結(jié)點(diǎn):
本例中我們感興趣的是FeatureNode。
開始
MSDN上有一篇非常棒的文章介紹了如何擴(kuò)展Visual Studio Tools for SharePoint
下圖是我們將要進(jìn)行的工作的圖形化表示:
1、新建一個(gè)類,并實(shí)現(xiàn)IExplorerNodeTypeExtension接口
2、處理事件
3、通過(guò)Annotations 訪問(wèn)該結(jié)點(diǎn)的屬性
4、通過(guò)客戶端對(duì)象模型執(zhí)行SharePoint操作
***步
創(chuàng)建一個(gè)Windows類庫(kù)項(xiàng)目并添加下列引用
第二步
創(chuàng)建一個(gè)類并實(shí)現(xiàn)接口IExplorerNodeTypeExtension:
第三步
我們感興趣的是在上下文菜單中添加一項(xiàng),處理事件NodeMenuItemsRequested。這些都在Initialize方法中完成:
- public void Initialize(IExplorerNodeType nodeType)
- {
- nodeType.NodeMenuItemsRequested +=
- new EventHandler<ExplorerNodeMenuItemsRequestedEventArgs>
- (nodeType_NodeMenuItemsRequested);
- }
在下面添加事件處理程序:
- void nodeType_NodeMenuItemsRequested(object sender, ExplorerNodeMenuItemsRequestedEventArgs e)
- {
- IMenuItem deactivateMenu = e.MenuItems.Add("停用");
- deactivateMenu.Click +=
- new EventHandler<MenuItemEventArgs>(deactivateMenu_Click);
- }
我們?cè)谑录幚沓绦蛑刑砑恿艘粋€(gè)菜單項(xiàng)并且處理了其自身的點(diǎn)擊事件。
第四步
我們?nèi)粢S靡粋€(gè)功能,首先需要知道該功能的Definition Id。在功能的屬性面板中已經(jīng)有這個(gè)值了:
為了訪問(wèn)該屬性,我們需要借助于Annotations對(duì)象。下面是訪問(wèn)功能屬性的代碼:
- IFeatureNodeInfo fn = e.Node.Annotations[typeof(IFeatureNodeInfo)] as IFeatureNodeInfo;
- definitionId = fn.Id;
- featureName = fn.Name;
接下來(lái)我們要獲取該功能所處的網(wǎng)站。因?yàn)榉?wù)器資源管理器已經(jīng)實(shí)例化了到該站點(diǎn)的連接,因此我們可以直接從當(dāng)前上下文中獲取。
- IExplorerNodeContext siteContext = e.Node.Context;
下面是事件處理程序代碼現(xiàn)在的樣子:
- void nodeType_NodeMenuItemsRequested(object sender, ExplorerNodeMenuItemsRequestedEventArgs e)
- {
- siteContext = e.Node.Context;
- IFeatureNodeInfo fn = e.Node.Annotations[typeof(IFeatureNodeInfo)] as IFeatureNodeInfo;
- definitionId = fn.Id;
- featureName = fn.Name;
- IMenuItem deactivateMenu = e.MenuItems.Add("停用");
- deactivateMenu.Click += new EventHandler<MenuItemEventArgs>(deactivateMenu_Click);
- }
第五步
現(xiàn)在我們可以通過(guò)客戶端對(duì)象模型在新菜單項(xiàng)的事件處理程序中編寫停用功能的代碼了:
- void deactivateMenu_Click(object sender, MenuItemEventArgs e)
- {
- if (MessageBox.Show(confirmationMessage,String.Format("停用{0} 功能",featureName),
- MessageBoxButtons.YesNo,
- MessageBoxIcon.Exclamation) == DialogResult.Yes)
- {
- IExplorerNode parentFeatureNode = e.Owner as IExplorerNode;
- IExplorerNode featureNode = parentFeatureNode.ParentNode;
- ClientContext clientContext = new ClientContext(siteContext.SiteUrl.AbsoluteUri);
- Web site = clientContext.Web;
- FeatureCollection siteFeatures = site.Features;
- clientContext.Load(site, s => s.Title, s => s.Features);
- siteFeatures.Remove(definitionId, false);
- clientContext.ExecuteQuery();
- clientContext.Dispose();
- featureNode.Refresh();
- }
- }
確實(shí)很簡(jiǎn)單。查詢并僅返回Web和Features對(duì)象,然后從該站點(diǎn)中Remove(停用)該功能。
你也可以通過(guò)客戶端對(duì)象模型的異步模式來(lái)實(shí)現(xiàn)異步調(diào)用。
部署該擴(kuò)展
為了能夠部署這個(gè)擴(kuò)展,我們需要將其包含到一個(gè).vsix包中。
你可以套用VSIX模板來(lái)創(chuàng)建.vsix包。
在manifest文件中包含該擴(kuò)展。
選擇內(nèi)容為MEF Component,并選擇擴(kuò)展項(xiàng)目作為源。
編譯該項(xiàng)目并生成相應(yīng)的.vsix包,然后安裝這個(gè)包。
為FeatureNode所開發(fā)的“停用擴(kuò)展”就完成了
現(xiàn)在看看上下文菜單,已經(jīng)出現(xiàn)我們的菜單項(xiàng)了:
當(dāng)你點(diǎn)擊它時(shí),會(huì)彈出確認(rèn)消息:
點(diǎn)"是"的話將停用該功能并刷新功能結(jié)點(diǎn)樹視圖。