如何:扩展服务器资源管理器中的 SharePoint 节点

您可以在**“服务器资源管理器”中的“SharePoint 连接”**节点下扩展节点。 这对于需要向现有节点中添加新的子节点、快捷菜单项或属性的情况非常有用。 有关更多信息,请参见扩展服务器资源管理器中的“SharePoint 连接”节点

扩展服务器资源管理器中的 SharePoint 节点

  1. 创建一个类库项目。

  2. 添加对下列程序集的引用:

    • Microsoft.VisualStudio.SharePoint

    • Microsoft.VisualStudio.SharePoint.Explorer.Extensions

    • System.ComponentModel.Composition

  3. 创建一个实现 IExplorerNodeTypeExtension 接口的类。

  4. 给类添加 System.ComponentModel.Composition.ExportAttribute 特性。 此特性使 Visual Studio 能够发现并加载您的 IExplorerNodeTypeExtension 实现。 将 IExplorerNodeTypeExtension 类型传递给特性构造函数。

  5. 给类添加 ExplorerNodeTypeAttribute 特性。 此特性指定要扩展的节点类型的字符串标识符。

    若要指定 Visual Studio 提供的内置节点类型,请将以下枚举值之一传递给特性构造函数:

    • ExplorerNodeTypes:使用这些值可在**“服务器资源管理器”**中指定网站连接节点(即显示网站 URL 的节点)、网站节点或所有其他父节点。

    • ExtensionNodeTypes:使用这些值可指定表示 SharePoint 网站上的单个组件的内置节点之一,如表示列表、字段或内容类型的节点。

  6. IExplorerNodeTypeExtension.Initialize 方法的实现中,使用 nodeType 参数的成员以将功能添加到节点中。 此参数是一个 IExplorerNodeType 对象,它提供对 IExplorerNodeEvents 接口中定义的事件的访问。 例如,您可以处理以下事件:

示例

下面的代码示例演示如何创建两种不同类型的节点扩展:

  • 将上下文菜单项添加到 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 节点

演练:扩展服务器资源管理器以显示 Web 部件

其他资源

扩展服务器资源管理器中的“SharePoint 连接”节点

将自定义数据与 SharePoint 工具扩展相关联