in SharePoint 2010

SharePoint 2010: Extending a SharePoint Node in Server Explorer

SharePoint Server Explorer is a new addition to Visual Studio 2010 along with the Visual Studio Tools for SharePoint.

image

It is a very good tool if you want to browse the contents (site columns, content types, features etc.,) of the SharePoint site from Visual Studio. By default, it doesn’t do nothing much than showing what are available in the site.

image

As you can see, the context menu has very fewer items. Below is the Properties pane for the Holds list in the screenshot. The properties are stored in Annotations. To understanding what Annotations are, it is best to consider them as a Class with Properties. Those properties is what you see in the Properties pane below.

image

Again, its read only.

Can I Extend?

So, the next obvious question you would ask yourself (if you are a SharePoint developer) is – Can I extend this and add my own commands or nodes to the SharePoint Server Explorer?

Yes, you can extend the SharePoint Server Explorer to:

1) Create new nodes

2) Extend existing nodes

Give me an example?

Lets take the Features node

image

The Features node displays all the active features in the site. If you right click on a feature, you get very less options

image

How cool would be to add Deactivate option to the context menu and deactivate the selected feature? 🙂

image

[ By the way, the above screenshot is an actual extension built and not a Photoshop trick 🙂 ]

Understanding the SharePoint Server Explorer

Before you start writing an extension, you should get to know the different types of SharePoint Server Explorer nodes.

image

The node that we are interested in is the FeatureNode.

Getting Started

MSDN has excellent articles explaining how to extend the Visual Studio Tools for SharePoint

Here is a pictorial representation of what we would be doing:

image

 

1. Create a class that implements IExplorerNodeTypeExtension

2. Handle the events

3. Access the properties of that node using Annotations

4. Perform SharePoint operations using Client Object Model

Step 1

Create a Windows Class Library project and add references to

  • Microsoft.VisualStudio.SharePoint

  • Microsoft.VisualStudio.SharePoint.Explorer.Extensions

  • System.ComponentModel.Composition

 

Step 2

Create a class and implement IExplorerNodeTypeExtension:

internal class FeatureNodeExtension : IExplorerNodeTypeExtension
{

}

 

Step 3

As we are interested in adding an item to the context menu, handle the NodeMenuItemsRequested. This is done in the Initialize method:

public void Initialize(IExplorerNodeType nodeType)
{
nodeType.NodeMenuItemsRequested +=
new EventHandler<ExplorerNodeMenuItemsRequestedEventArgs>
(nodeType_NodeMenuItemsRequested);
}

 

And here is the event handler:

void nodeType_NodeMenuItemsRequested(object sender, ExplorerNodeMenuItemsRequestedEventArgs e)
{
IMenuItem deactivateMenu = e.MenuItems.Add("Deactivate");
deactivateMenu.Click +=
new EventHandler<MenuItemEventArgs>(deactivateMenu_Click);
}

We add the new menu item in the event handler above and also handle its own click event.

Step 4

As we want to deactivate a feature, we need to know the Feature Definition Id. They are already available in the Properties pane for a feature:

image

To access the Properties we need to access it via the Annotations object. Here is the code to access the Feature properties:

IFeatureNodeInfo fn = e.Node.Annotations[typeof(IFeatureNodeInfo)] as IFeatureNodeInfo;
definitionId = fn.Id;
featureName = fn.Name;

 

Next thing is to get the site at which this feature is installed. As the Server Explorer has already established the connection to the site, we can get it from its current context.

IExplorerNodeContext siteContext = e.Node.Context;

 

Here is how my event handler looks:

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("Deactivate");
deactivateMenu.Click += new EventHandler<MenuItemEventArgs>(deactivateMenu_Click);
}

 

Step 5

We can now write code to deactivate the feature in the new menu item’s event handler using the Client Object Model:

void deactivateMenu_Click(object sender, MenuItemEventArgs e)
{
if (MessageBox.Show(confirmationMessage,String.Format("Deactivate {0} feature",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();
}
}

Very simple indeed. Query and get only the Web and Features object, and then remove (deactivate) the feature from the site.

You can also do this asynchronously using the Asynchronous Pattern for Client OM.

Deploying the Extension

To deploy the extension, we need to include it in a .vsix package.

You can use the VSIX template to create the .vsix package.

image

Include the extension in the manifest file.

image

Chose the content as MEF Component  and select the extensions project as your source.

Build the project to generate the .vsix package and install the package.

‘Deactivate Extension’ for FeaturesNode done

And here is our menu item in the context menu:

image

 

 

When you click on it, you will get a confirmation message:

image

Clicking Yes will deactivate the feature and refresh the Features node.

You can download the source code and VSIX package below:

Write a Comment

Comment

Time limit is exhausted. Please reload the CAPTCHA.