如何:扩展服务器资源管理器中的 SharePoint 节点
您可以在**“服务器资源管理器”中的“SharePoint 连接”**节点下扩展节点。 这对于需要向现有节点中添加新的子节点、快捷菜单项或属性的情况非常有用。 有关更多信息,请参见扩展服务器资源管理器中的“SharePoint 连接”节点。
扩展服务器资源管理器中的 SharePoint 节点
创建一个类库项目。
添加对下列程序集的引用:
Microsoft.VisualStudio.SharePoint
Microsoft.VisualStudio.SharePoint.Explorer.Extensions
System.ComponentModel.Composition
创建一个实现 IExplorerNodeTypeExtension 接口的类。
给类添加 System.ComponentModel.Composition.ExportAttribute 特性。 此特性使 Visual Studio 能够发现并加载您的 IExplorerNodeTypeExtension 实现。 将 IExplorerNodeTypeExtension 类型传递给特性构造函数。
给类添加 ExplorerNodeTypeAttribute 特性。 此特性指定要扩展的节点类型的字符串标识符。
若要指定 Visual Studio 提供的内置节点类型,请将以下枚举值之一传递给特性构造函数:
ExplorerNodeTypes:使用这些值可在**“服务器资源管理器”**中指定网站连接节点(即显示网站 URL 的节点)、网站节点或所有其他父节点。
ExtensionNodeTypes:使用这些值可指定表示 SharePoint 网站上的单个组件的内置节点之一,如表示列表、字段或内容类型的节点。
在 IExplorerNodeTypeExtension.Initialize 方法的实现中,使用 nodeType 参数的成员以将功能添加到节点中。 此参数是一个 IExplorerNodeType 对象,它提供对 IExplorerNodeEvents 接口中定义的事件的访问。 例如,您可以处理以下事件:
IExplorerNodeEvents.NodeChildrenRequested:处理此事件可将新的子节点添加到节点中。 有关更多信息,请参见如何:向服务器资源管理器添加自定义 SharePoint 节点。
IExplorerNodeEvents.NodeMenuItemsRequested:处理此事件可将自定义快捷菜单项添加到节点中。
IExplorerNodeEvents.NodePropertiesRequested:处理此事件可将自定义属性添加到节点中。 选定相关节点后,所添加的自定义属性将会出现在**“属性”**窗口中。
示例
下面的代码示例演示如何创建两种不同类型的节点扩展:
将上下文菜单项添加到 SharePoint 网站节点的扩展。 当单击菜单项时,它显示所单击节点的名称。
将名为**“ContosoExampleProperty”的自定义属性添加到表示名为“Body”**的字段的每个节点的扩展。
Imports System.ComponentModel
Imports System.ComponentModel.Composition
Imports System.Windows.Forms
Imports Microsoft.VisualStudio.SharePoint
Imports Microsoft.VisualStudio.SharePoint.Explorer
Imports Microsoft.VisualStudio.SharePoint.Explorer.Extensions
Namespace Contoso.ServerExplorerExtension
<Export(GetType(IExplorerNodeTypeExtension))> _
<ExplorerNodeType(ExplorerNodeTypes.SiteNode)> _
Friend Class SiteNodeExtensionWithContextMenu
Implements IExplorerNodeTypeExtension
Private Sub Initialize(ByVal nodeType As IExplorerNodeType) _
Implements IExplorerNodeTypeExtension.Initialize
AddHandler nodeType.NodeMenuItemsRequested, AddressOf NodeMenuItemsRequested
End Sub
Private Sub NodeMenuItemsRequested(ByVal Sender As Object, ByVal e As ExplorerNodeMenuItemsRequestedEventArgs)
Dim menuItem = e.MenuItems.Add("Display Message")
AddHandler menuItem.Click, AddressOf MenuItemClick
End Sub
Private Sub MenuItemClick(ByVal Sender As Object, ByVal e As MenuItemEventArgs)
Dim node As IExplorerNode = CType(e.Owner, IExplorerNode)
MessageBox.Show(String.Format("Clicked the menu item for the '{0}' node.", node.Text))
End Sub
End Class
<Export(GetType(IExplorerNodeTypeExtension))> _
<ExplorerNodeType(ExtensionNodeTypes.FieldNode)> _
Friend Class FieldNodeExtensionWithProperty
Implements IExplorerNodeTypeExtension
Private Sub Initialize(ByVal nodeType As IExplorerNodeType) _
Implements IExplorerNodeTypeExtension.Initialize
AddHandler nodeType.NodePropertiesRequested, AddressOf NodePropertiesRequested
End Sub
Private Sub NodePropertiesRequested(ByVal Sender As Object, ByVal e As ExplorerNodePropertiesRequestedEventArgs)
Dim propertyObject As ExampleProperty = Nothing
' Only add the property to "Body" fields.
If e.Node.Text = "Body" Then
' If the properties object already exists for this node, get it from the node's annotations.
If False = e.Node.Annotations.TryGetValue(propertyObject) Then
' Otherwise, create a new properties object and add it to the annotations.
propertyObject = New ExampleProperty(e.Node)
e.Node.Annotations.Add(propertyObject)
End If
e.PropertySources.Add(propertyObject)
End If
End Sub
End Class
Friend Class ExampleProperty
Private node As IExplorerNode
Private Const propertyId As String = "Contoso.CustomActionTestProperty"
Private Const propertyDefaultValue As String = "This is a test value."
Friend Sub New(ByVal node As IExplorerNode)
Me.node = node
End Sub
' Gets or sets a simple string property.
<DisplayName("ContosoExampleProperty")> _
<DescriptionAttribute("This is an example property for field nodes.")> _
<DefaultValue(propertyDefaultValue)> _
Public Property TestProperty As String
Get
Dim propertyValue As String = Nothing
' Get the current property value if it already exists; otherwise, return a default value.
If False = node.Annotations.TryGetValue(propertyId, propertyValue) Then
propertyValue = propertyDefaultValue
End If
Return propertyValue
End Get
Set(ByVal value As String)
If value <> propertyDefaultValue Then
' Store the property value in the Annotations property of the node.
' Data in the Annotations property does not persist when Visual Studio exits.
node.Annotations(propertyId) = value
Else
' Do not save the default value.
node.Annotations.Values.Remove(propertyId)
End If
End Set
End Property
End Class
End Namespace
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Windows.Forms;
using Microsoft.VisualStudio.SharePoint;
using Microsoft.VisualStudio.SharePoint.Explorer;
using Microsoft.VisualStudio.SharePoint.Explorer.Extensions;
namespace Contoso.ServerExplorerExtension
{
[Export(typeof(IExplorerNodeTypeExtension))]
[ExplorerNodeType(ExplorerNodeTypes.SiteNode)]
internal class SiteNodeExtensionWithContextMenu : IExplorerNodeTypeExtension
{
public void Initialize(IExplorerNodeType nodeType)
{
nodeType.NodeMenuItemsRequested += nodeType_NodeMenuItemsRequested;
}
void nodeType_NodeMenuItemsRequested(object sender, ExplorerNodeMenuItemsRequestedEventArgs e)
{
IMenuItem menuItem = e.MenuItems.Add("Display Message");
menuItem.Click += menuItem_Click;
}
void menuItem_Click(object sender, MenuItemEventArgs e)
{
IExplorerNode node = (IExplorerNode)e.Owner;
MessageBox.Show(string.Format("Clicked the menu item for the '{0}' node.", node.Text));
}
}
[Export(typeof(IExplorerNodeTypeExtension))]
[ExplorerNodeType(ExtensionNodeTypes.FieldNode)]
internal class FieldNodeExtensionWithProperty : IExplorerNodeTypeExtension
{
public void Initialize(IExplorerNodeType nodeType)
{
nodeType.NodePropertiesRequested += nodeType_NodePropertiesRequested;
}
void nodeType_NodePropertiesRequested(object sender, ExplorerNodePropertiesRequestedEventArgs e)
{
// Only add the property to "Body" fields.
if (e.Node.Text == "Body")
{
ExampleProperty propertyObject;
// If the properties object already exists for this node, get it from the node's annotations.
if (!e.Node.Annotations.TryGetValue(out propertyObject))
{
// Otherwise, create a new properties object and add it to the annotations.
propertyObject = new ExampleProperty(e.Node);
e.Node.Annotations.Add(propertyObject);
}
e.PropertySources.Add(propertyObject);
}
}
}
internal class ExampleProperty
{
private IExplorerNode node;
private const string propertyId = "Contoso.ExampleProperty";
private const string propertyDefaultValue = "This is an example property.";
internal ExampleProperty(IExplorerNode node)
{
this.node = node;
}
// Gets or sets a simple string property.
[DisplayName("ContosoExampleProperty")]
[DescriptionAttribute("This is an example property for field nodes.")]
[DefaultValue(propertyDefaultValue)]
public string TestProperty
{
get
{
string propertyValue;
// Get the current property value if it already exists; otherwise, return a default value.
if (!node.Annotations.TryGetValue(propertyId, out propertyValue))
{
propertyValue = propertyDefaultValue;
}
return propertyValue;
}
set
{
if (value != propertyDefaultValue)
{
// Store the property value in the Annotations property of the node.
// Data in the Annotations property does not persist when Visual Studio exits.
node.Annotations[propertyId] = value;
}
else
{
// Do not save the default value.
node.Annotations.Remove(propertyId);
}
}
}
}
}
此扩展会将可编辑的字符串属性添加到节点中。 还可以创建用于显示 SharePoint 服务器的只读数据的自定义属性。 有关演示如何执行此操作的示例,请参见演练:扩展服务器资源管理器以显示 Web 部件。
编译代码
此示例需要对以下程序集的引用:
Microsoft.VisualStudio.SharePoint
Microsoft.VisualStudio.SharePoint.Explorer.Extensions
System.ComponentModel.Composition
System.Windows.Forms
部署扩展
若要部署**“服务器资源管理器”**扩展,请为要利用此扩展分发的程序集和任何其他文件创建 Visual Studio 扩展 (VSIX) 包。 有关更多信息,请参见在 Visual Studio 中部署 SharePoint 工具扩展。
请参见
任务
如何:向服务器资源管理器添加自定义 SharePoint 节点