Creating a Web Part with a Custom Tool Part

You can use a custom tool part to create a custom user interface for your properties that goes well beyond the capabilities of the default property pane. This programming task describes how to create a Web Part with a custom tool part.

To start this programming task  

  • Perform the steps described in the Creating a Basic Web Part programming task up to the steps for "Defining the Rendering and Logic of Your Web Part."

There are two high-level steps that you must perform to create a custom tool part and associate it with your Web Part:

  • Add a GetToolParts method to your Web Part class (an example is provided for you as part of the Web Part template that you can download from MSDN)
  • Create your custom tool part's class

Add a GetToolParts Method to Your Web Part Class

To determine which tool parts to include in the property pane for your Web Part, you must override the GetToolParts method of the WebPart base class in your Web Part's class. The GetToolPart method returns an array of references to the new ToolPart objects that will be displayed in the property pane for your Web Part. The ToolPart objects are rendered by the tool pane in the order listed in the array. This provides you with the ability to show multiple ToolParts if your Web Part requires them. Note that when you override the WebPart class's GetToolParts method, the default ToolPart objects (WebPartToolPart and CustomPropertyToolPart) aren't displayed automatically. You must include code to display them.

By default, the GetToolParts method will return the CustomPropertyToolPart and WebPartToolPart objects. The CustomPropertyToolPart object will display the built-in tool part that is shown by default for custom properties as described in the "Creating a Web Part with Custom Properties" programming task. If you want to display some of the custom properties for your Web Part using the built-in custom properties tool part, you must include a reference to the CustomPropertyToolPart object in the array of references returned by your GetToolParts method. The WebPartToolPart object will display all the base class properties of the Web Part. After the Web Part developer overrides this method, he has to specifically opt to show these default tool parts.

Because this example uses the SPEncode Class, it requires a using directive (Imports in Visual Basic) for the Microsoft.SharePoint.Utilities namespace.

The following code is the example you will find in the Web Part template that illustrates how the GetToolParts method is implemented by default.

/// <summary>
/// Gets the custom tool parts for this Web Part by overriding the
/// GetToolParts method of the WebPart base class. You must implement
/// custom tool parts in a separate class that derives from
/// Microsoft.SharePoint.WebPartPages.ToolPart.
/// </summary>
///<returns>An array of references to ToolPart objects.</returns>

// public override ToolPart[] GetToolParts()
//{
//  ToolPart[] toolparts = new ToolPart[2];
//  WebPartToolPart wptp = new WebPartToolPart();
//  CustomPropertyToolPart custom = new CustomPropertyToolPart();
//  toolparts[0] = custom;
//  toolparts[1] = wptp;
//  return toolparts;
//}

The following code sample shows a complete Web Part class that implements a single custom property that will be displayed in a custom tool part.

//---------------------------------------------------------
// File : SimpleWebPart.cs
//
// Purpose : A simple Web Part that implements one custom
//           property.
//---------------------------------------------------------

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;

namespace WebPartLibrary2
{
/// <summary>
    /// Summary description for SimpleWebPart.
    /// </summary>
    [DefaultProperty("Text"),
        ToolboxData("<{0}:SimpleWebPart runat=server></{0}:SimpleWebPart>"),
        XmlRoot(Namespace="WebPartLibrary2")]
    
public class SimpleWebPart : Microsoft.SharePoint.WebPartPages.WebPart
    {
        private const string defaultText = "Your text here";
        private string text = defaultText;

        [Browsable(false),Category("Miscellaneous"),
        DefaultValue(defaultText),
        WebPartStorage(Storage.Personal),
        FriendlyName("Text"),Description("Text Property")]
        public string Text
        {
            get
            {
                return text;
            }

            set
            {
                text = value;
            }
        }
        
        /// <summary>
        /// Gets the custom tool parts for this Web Part by
/// overriding the GetToolParts method of the WebPart
/// base class. You must implement custom tool parts in
/// a separate class that derives from
/// Microsoft.SharePoint.WebPartPages.ToolPart.
        /// </summary>
        ///<returns>
/// An array of references to ToolPart objects.
///</returns>
        public override ToolPart[] GetToolParts()
        {
            ToolPart[] toolparts = new ToolPart[3];
            WebPartToolPart wptp = new WebPartToolPart();
CustomPropertyToolPart custom = new CustomPropertyToolPart();
            toolparts[0] = custom;
            toolparts[1] = wptp;

            // This is the custom ToolPart.
            toolparts[2] = new WebPartLibrary2.ToolPart1();

            return toolparts;
        }

        /// <summary>
        /// Render this Web Part to the output parameter specified.
        /// </summary>
        /// <param name="output">
/// The HTML writer to write out to
/// </param>
protected override void RenderWebPart(HtmlTextWriter output)
        {
output.Write(SPEncode.HtmlEncode("Your custom text is: <b>" + this.Text + "</b><hr>"));

        }
    }
}

Create Your Custom ToolPart's Class

After you have added the GetToolParts method to your Web Part, you need to create a separate class for your tool part itself. There are two high-level steps that you must perform to create a custom tool part:

  • Add a New Class to Your Project
  • Override the ApplyChanges Method

Add a New Class to Your Project

First, you need to create another class in the same project as your Web Part to define your tool part.

To add a new class for your tool part using Web Part templates  

  • In Solution Explorer, right click your Web Part's node, point to Add, and then click Add New Item.
  • Select the ToolPart template located under Local Project Items>Code.
  • Click Open.

To add a new class for your tool part  

  • In Solution Explorer, right click your Web Part's node, point to Add, and then click Add Class.

  • Select the Web Custom Control template.

  • Change the name to ToolPart1.cs, and click Open.

  • Add a using directive for the WebPartPages namespace near the top of your code:

    using Microsoft.SharePoint.WebPartPages;
    
  • Make your ToolPart1 class inherit from the ToolPart class:

    public class ToolPart1 : ToolPart
    

Override the ApplyChanges Method

As its name implies, the ApplyChanges method applies the changes made in your tool part back to the Web Part it is associated with. Because ApplyChanges is a virtual method, you must override it to implement it in your tool part. The ApplyChanges method is called when the user clicks OK or Apply in the property pane. This is where you send the value of any updated properties back to the Web Part.

To obtain a reference to the Web Part to update its properties, the ToolPart class has an accessor property called ParentToolPane that returns a reference to the ToolPane object. The ToolPane object is the class that keeps track of which Web Part is selected, and in turn, it has an accessor property called SelectedWebPart that returns a WebPart object for the current Web Part.

To complete this programming task  

  • Cut and paste the following code sample into the ToolPart1.cs file for your Web Part project, and then build your project.

    Because this example uses the SPEncode Class, it requires a using directive (Imports in Visual Basic) for the Microsoft.SharePoint.Utilities namespace.

//---------------------------------------------------------
// File : ToolPart1.cs
//
// Purpose : A sample tool part that sets the CustomText
//           property of WebPart1.
//---------------------------------------------------------

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;

namespace WebPartLibrary2
{
    /// <summary>
    /// Description of the toolpart. Override the GetToolParts method
    /// in your Web Part class to invoke this toolpart. To establish
    /// a reference to the Web Part the user has selected, use the
    /// ParentToolPane.SelectedWebPart property.
    /// </summary>
    public class ToolPart1:
    Microsoft.SharePoint.WebPartPages.ToolPart
    {
        // declaring a sample varialble
        private string inputname;

        // an event handler for the Init event
        private void ToolPart1_Init(object sender,
            System.EventArgs e )
        {
            inputname = this.UniqueID + "message";
        }

        /// <summary>
        /// Constructor for the class. A great place to set Set
        /// default values for additional base class properties
        /// here.
        /// <summary>

        public ToolPart1()
        {
            // Set default properties
            this.Title="Custom Text";
            this.Init += new EventHandler(ToolPart1_Init);
        }
        /// <summary>
        /// Called by the tool pane to apply property changes to
        /// the selected Web Part.
        /// </summary>
        public override void ApplyChanges()
        {
            SimpleWebPart wp1 = (SimpleWebPart)
            this.ParentToolPane.SelectedWebPart;
            
            // Send the custom text to the Web Part.
            wp1.Text = Page.Request.Form[inputname];
        }

        /// <summary>
        /// If the ApplyChanges method succeeds, this method is
        /// called by the tool pane to refresh the specified
        /// property values in the toolpart user interface.
        /// </summary>
        public override void SyncChanges()
        {
            // sync with the new property changes here
        }
        
        /// <summary>
        /// Called by the tool pane if the user discards changes
        /// to the selected Web Part.
        /// </summary>
        public override void CancelChanges()
        {
        }
        /// <summary>
        /// Render this Tool part to the output parameter
        /// specified.
        /// </summary>
        /// <param name="output">
        /// The HTML writer to write out to
        /// </param>
        protected override void RenderToolPart(HtmlTextWriter output)
        {
            // Establish a reference to the Web Part.
            SimpleWebPart wp1 = (SimpleWebPart)
            this.ParentToolPane.SelectedWebPart;
            output.Write("Enter your custom text: ");
            output.Write("<input name= '" + inputname );
            output.Write("' type='text' value='" + SPEncode.HtmlEncode(wp1.Text) + "'> <br>");
        }
    }                                           
}

To deploy this sample Web Part  

  • Perform the steps described in the "Deploying Your Web" section of the "Create a Basic Web Part" programming task, making sure to create a SafeControl block and Web Part Definition file (.dwp) that reflects the appropriate values for your Web Part assembly.