How to: Add a Property to SharePoint Projects

You can use a project extension to add a property to any SharePoint project. The property appears in the Properties window when the project is selected in Solution Explorer.

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

To add a property to a SharePoint project

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

  2. In the Initialize method of your ISharePointProjectExtension implementation, handle the ProjectPropertiesRequested event of the projectService parameter.

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

The following code example demonstrates how to add two properties to SharePoint projects. One property persists its data in the project user option file (the .csproj.user file or .vbproj.user file). The other property persists its data in the project file (.csproj file or .vbproj file).

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

namespace CustomSharePointProperty
{
    [Export(typeof(ISharePointProjectExtension))]
    public class ProjectExtensionWithProperty : ISharePointProjectExtension
    {
        public void Initialize(ISharePointProjectService projectService)
        {
            projectService.ProjectPropertiesRequested += projectService_ProjectPropertiesRequested;           
        }

        void projectService_ProjectPropertiesRequested(object sender, SharePointProjectPropertiesRequestedEventArgs e)
        {
            CustomProjectProperties propertiesObject;

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

            e.PropertySources.Add(propertiesObject);
        }
    }

    public class CustomProjectProperties
    {
        private ISharePointProject sharePointProject;
        private IVsBuildPropertyStorage projectStorage;
        private const string ProjectFilePropertyId = "ContosoCustomProjectFileProperty";
        private const string ProjectFilePropertyDefaultValue = "Default";

        public CustomProjectProperties(ISharePointProject myProject)
        {
            sharePointProject = myProject;
            projectStorage = sharePointProject.ProjectService.Convert<ISharePointProject, IVsBuildPropertyStorage>(sharePointProject);
        }

        [DisplayName("Custom Project File Property")]
        [DescriptionAttribute("This property is saved to the .csproj/.vbproj file.")]
        [DefaultValue(ProjectFilePropertyDefaultValue)]
        public string CustomProjectFileProperty
        {
            get
            {
                string propertyValue;
                int hr = projectStorage.GetPropertyValue(ProjectFilePropertyId, string.Empty, 
                    (uint)_PersistStorageType.PST_PROJECT_FILE, out propertyValue);

                // Try to get the current value from the project file; if it does not yet exist, return a default value. 
                if (!ErrorHandler.Succeeded(hr) || String.IsNullOrEmpty(propertyValue))
                {
                    propertyValue = ProjectFilePropertyDefaultValue;
                }

                return propertyValue;
            }

            set
            {
                // Do not save the default value. 
                if (value != ProjectFilePropertyDefaultValue)
                {
                    projectStorage.SetPropertyValue(ProjectFilePropertyId, string.Empty, 
                        (uint)_PersistStorageType.PST_PROJECT_FILE, value);
                }
            }
        }

        private const string UserFilePropertyId = "ContosoCustomUserFileProperty";
        private const string UserFilePropertyDefaultValue = "Default";

        [DisplayName("Custom Project User File Property")]
        [DescriptionAttribute("This property is saved to the .user file.")]
        [DefaultValue(UserFilePropertyDefaultValue)]
        public string CustomUserFileProperty
        {
            get
            {
                string propertyValue = string.Empty;

                // Try to get the current value from the .user file; if it does not yet exist, return a default value. 
                if (!sharePointProject.ProjectUserFileData.TryGetValue(UserFilePropertyId, out propertyValue))
                {
                    propertyValue = UserFilePropertyDefaultValue; 
                }

                return propertyValue; 
            }

            set
            {
                // Do not save the default value. 
                if (value != UserFilePropertyDefaultValue)
                {
                    sharePointProject.ProjectUserFileData[UserFilePropertyId] = value;
                }
            }
        }                
    }
}

To ensure that the same instance of the CustomProjectProperties class is used each time the ProjectPropertiesRequested event occurs, the code example adds the properties object to the Annotations property of the project 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 projects, see Associating Custom Data with SharePoint Tools Extensions.

To persist changes to the property values, the set accessors for the properties use the following APIs:

For more information about persisting data in these files, see Saving Data in Extensions of the SharePoint Project System.

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.

This example requires references to the following assemblies:

  • Microsoft.VisualStudio.SharePoint

  • Microsoft.VisualStudio.Shell

  • Microsoft.VisualStudio.Shell.Interop

  • Microsoft.VisualStudio.Shell.Interop.8.0

  • System.ComponentModel.Composition

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 Deploying Extensions for the SharePoint Tools in Visual Studio.

Was this page helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft