How to: Add a property to a SharePoint project item extension

Applies to: yesVisual Studio noVisual Studio for Mac

Note

This article applies to Visual Studio 2017. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here

You can use a project item extension to add a property to any SharePoint project item that is already installed in Visual Studio. The property appears in the Properties window when the project item is selected in Solution Explorer.

The following steps assume that you have already created a project item extension. For more information, see How to: Create a SharePoint Project Item Extension.

To add a property to a project item extension

  1. Define a class with a public property that represents the property you are adding to a project item type. If you want to add multiple properties to a project item type, you can define all the properties in the same class or in different classes.

  2. In the Initialize method of your ISharePointProjectItemTypeExtension implementation, handle the ProjectItemPropertiesRequested event of the projectItemType parameter.

  3. In the event handler for the ProjectItemPropertiesRequested event, add an instance of your properties class to the PropertySources collection of the event arguments parameter.

Example

The following code example demonstrates how to add a property named Example Property to the Event Receiver project item.

using System;
using System.ComponentModel;
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.SharePoint;

namespace Contoso.Examples.ProjectItemExtensionWithProperty
{
    [Export(typeof(ISharePointProjectItemTypeExtension))]
    [SharePointProjectItemType("Microsoft.VisualStudio.SharePoint.EventHandler")]
    internal class ExampleProjectItemExtensionWithProperty : ISharePointProjectItemTypeExtension
    {
        public void Initialize(ISharePointProjectItemType projectItemType)
        {
            projectItemType.ProjectItemPropertiesRequested += 
                projectItemType_ProjectItemPropertiesRequested;
        }

        void projectItemType_ProjectItemPropertiesRequested(object sender, 
            SharePointProjectItemPropertiesRequestedEventArgs e)
        {
            CustomProperties propertyObject;

            // If the properties object already exists, get it from the project item's annotations.
            if (!e.ProjectItem.Annotations.TryGetValue(out propertyObject))
            {
                // Otherwise, create a new properties object and add it to the annotations.
                propertyObject = new CustomProperties(e.ProjectItem);
                e.ProjectItem.Annotations.Add(propertyObject);
            }

            e.PropertySources.Add(propertyObject);
        }
    }

    internal class CustomProperties
    {
        private ISharePointProjectItem projectItem;

        internal CustomProperties(ISharePointProjectItem projectItem)
        {
            this.projectItem = projectItem;
        }

        private const string PropertyId = "Contoso.ExampleProperty";
        private const string PropertyDefaultValue = "This is an example property.";

        [DisplayName("Example Property")]
        [DescriptionAttribute("This is an example property for project items.")]
        [DefaultValue(PropertyDefaultValue)]
        public string ExampleProperty
        {
            get
            {
                string propertyValue;

                // Get the current property value if it already exists; otherwise, return a default value.
                if (!projectItem.ExtensionData.TryGetValue(PropertyId, out propertyValue))
                {
                    propertyValue = PropertyDefaultValue;
                }
                return propertyValue;
            }
            set
            {
                if (value != PropertyDefaultValue)
                {
                    // Store the property value in the ExtensionData property of the project item. 
                    // Data in the ExtensionData property persists when the project is closed.
                    projectItem.ExtensionData[PropertyId] = value;
                }
                else
                {
                    // Do not save the default value.
                    projectItem.ExtensionData.Remove(PropertyId);
                }
            }
        }
    }
}
Imports System
Imports System.ComponentModel
Imports System.ComponentModel.Composition
Imports Microsoft.VisualStudio.SharePoint

Namespace Contoso.Examples.ProjectItemExtensionWithProperty

    <Export(GetType(ISharePointProjectItemTypeExtension))> _
    <SharePointProjectItemType("Microsoft.VisualStudio.SharePoint.EventHandler")> _
    Friend Class ExampleProjectItemExtensionWithProperty
        Implements ISharePointProjectItemTypeExtension

        Private Sub Initialize(ByVal projectItemType As ISharePointProjectItemType) _
            Implements ISharePointProjectItemTypeExtension.Initialize
            AddHandler projectItemType.ProjectItemPropertiesRequested, AddressOf ProjectItemPropertiesRequested
        End Sub

        Private Sub ProjectItemPropertiesRequested(ByVal Sender As Object,
            ByVal e As SharePointProjectItemPropertiesRequestedEventArgs)
            Dim propertyObject As CustomProperties = Nothing

            ' If the properties object already exists, get it from the project item's annotations.
            If False = e.ProjectItem.Annotations.TryGetValue(propertyObject) Then
                ' Otherwise, create a new properties object and add it to the annotations.
                propertyObject = New CustomProperties(e.ProjectItem)
                e.ProjectItem.Annotations.Add(propertyObject)
            End If
            e.PropertySources.Add(propertyObject)
        End Sub
    End Class

    Friend Class CustomProperties
        Private projectItem As ISharePointProjectItem

        Friend Sub New(ByVal projectItem As ISharePointProjectItem)
            Me.projectItem = projectItem
        End Sub

        Private Const TestPropertyId As String = "Contoso.ExampleProperty"
        Private Const PropertyDefaultValue As String = "This is an example property."

        <DisplayName("Example Property")> _
        <DescriptionAttribute("This is an example property for project items.")> _
        <DefaultValue(PropertyDefaultValue)> _
        Public Property ExampleProperty As String
            Get
                Dim propertyValue As String = Nothing

                ' Get the current property value if it already exists; otherwise, return a default value.
                If False = projectItem.ExtensionData.TryGetValue(TestPropertyId, 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 ExtensionData property of the project item.
                    ' Data in the ExtensionData property persists when the project is closed.
                    projectItem.ExtensionData(TestPropertyId) = value
                Else
                    ' Do not save the default value.
                    projectItem.ExtensionData.Remove(TestPropertyId)
                End If
            End Set
        End Property
    End Class
End Namespace

Understand the code

To ensure that the same instance of the CustomProperties class is used each time the ProjectItemPropertiesRequested event occurs, the code example adds the properties object to the Annotations property of the project item the first time this event occurs. The code retrieves this object whenever this event occurs again. For more information about using the Annotations property to associate data with project items, see Associate custom data with SharePoint tools extensions.

To persist changes to the property value, the set accessor for ExampleProperty saves the new value to the ExtensionData property of the ISharePointProjectItem object that the property is associated with. For more information about using the ExtensionData property to persist data with project items, see Save data in extensions of the SharePoint project system.

Specify the behavior of custom properties

You can define how a custom property appears and behaves in the Properties window by applying attributes from the System.ComponentModel namespace to the property definition. The following attributes are useful in many scenarios:

  • DisplayNameAttribute: Specifies the name of the property that appears in the Properties window.

  • DescriptionAttribute: Specifies the description string that appears in the bottom of the Properties window when the property is selected.

  • DefaultValueAttribute: Specifies the default value of the property.

  • TypeConverterAttribute: Specifies a custom conversion between the string that is displayed in the Properties window and a non-string property value.

  • EditorAttribute: Specifies a custom editor to use to modify the property.

Compile the code

These examples require a class library project with references to the following assemblies:

  • Microsoft.VisualStudio.SharePoint

  • System.ComponentModel.Composition

Deploy the extension

To deploy the extension, create a Visual Studio extension (VSIX) package for the assembly and any other files that you want to distribute with the extension. For more information, see Deploy extensions for the SharePoint tools in Visual Studio.

See also