Writing Custom Editors for WebParts

The following WebPart may be simplistic, but it contains a “personalizable” public property called DisplayText that could transform it into an incredibly useful content editor:

public class SimpleWebPart : WebPart
{
   private string displayText = "Hello World!";

   [WebBrowsable(true), Personalizable(true)]
   public string DisplayText
   {
      get { return displayText; }
      set { displayText = value; }
   }

   protected override void Render(System.Web.UI.HtmlTextWriter writer)
   {
      writer.Write(displayText);
   }
}

The WebPart simply renders out the text specified in DisplayText, and putting it in either Microsoft Office SharePoint Server 2007 or an ASP.NET 2.0 WebPart framework that you wrote yourself enables you to modify the DisplayText value. In the case of an ASP.NET 2.0 WebPart framework, you can modify it with the PropertyGridEditorPart because DisplayText is decorated by the WebBrowsable(true) attribute.

This article describes how to write a custom editor for a WebPart. (If you haven’t already, read “ASP.NET 2.0: WebPart Framework Basics” for the necessary background to follow the discussion.) Because a custom editor written for an ASP.NET 2.0 WebPart is directly usable in SharePoint 2007, this article applies to both technologies equally well.

Custom Editor Basics

You could not only use the example WebPart as a content editor but also extend it into a cheap content management solution, particularly if you could hook it up with a standard Web-based HTML editor and give the user a better UI to edit his HTML than a tiny textbox. A number of free UI’s are available, but this article uses the telerik r.a.d. editor to write a custom EditorPart, which will hook up with the simple example WebPart.

Writing a custom editor basically is a two-step process:

  1. The WebPart needs to tell the framework which specific editors it wants to use. The framework then will add those editors into the EditorZone.
  2. You need to write the editors themselves. These simply inherit from the System.Web.UI.WebControls.WebParts.Editor class.

Look at these steps in turn.

Writing the EditorPart

As mentioned previously, the editor simply inherits from the EditorPart class. This class will require you to implement two methods:

  1. ApplyChanges: This method is responsible for taking the user’s current edits, as displayed in the editor, and apply them to the WebPart itself. In this case, this would mean setting a value to the DisplayText property.
  2. SyncChanges: This method is responsible for retrieving the current state of the WebPart and updating the editor itself to display the current state of the WebPart.

In either scenario, you can access the WebPart being edited by using the WebPartToEdit property available on the EditorPart itself.

With this knowledge, you can begin writing the EditorPart. Call it “HtmlEditor”. Your HtmlEditor will inherit from the EditorPart class and show the telerik r.a.d. editor in its UI. The following code achieves this very easily:

public class HtmlEditor : EditorPart
{
   private RadEditor htmlContentTxt;

   public HtmlEditor()
   {
      this.ID    = "HtmlEditor";
   }

   protected override void CreateChildControls()
   {
      htmlContentTxt               = new RadEditor();
      htmlContentTxt.ToolsFile     = "~/ToolsFile.xml";
      htmlContentTxt.BackColor     = System.Drawing.Color.White;
      htmlContentTxt.EnableDocking = false;
      htmlContentTxt.ToolbarMode   = EditorToolbarMode.ShowOnFocus;
      htmlContentTxt.ShowSubmitCancelButtons = false;
      htmlContentTxt.Modules.Clear();
      htmlContentTxt.Width  = new Unit("475px");
      htmlContentTxt.Height = new Unit("150px");
      Controls.Add(htmlContentTxt);
   }

   public override bool ApplyChanges()
   {
      // not implemented yet
   }

   public override void SyncChanges()
   {
      // not implemented yet
   }
}

Next, you need to implement ApplyChanges so it “applies the user’s changes to the WebPart”:

public override bool ApplyChanges()
{
   EnsureChildControls();
   SimpleWebPart part = WebPartToEdit as SimpleWebPart;
   if (part != null)
   {
      part.DisplayText = htmlContentTxt.Html;
   }
   else
   {
      return false;
   }
   return true;
}

Finally, you have to implement the SyncChanges method, so the EditorPart can apply the current state of the data in the WebPart to itself:

public override void SyncChanges()
{
   EnsureChildControls();
   SimpleWebPart part = WebPartToEdit as SimpleWebPart;
   if (part != null)
   {
      htmlContentTxt.Html = part.DisplayText;
   }
}

That’s it. You have set up your EditorPart. The next step is to tweak the WebPart itself, so it uses your EditorPart.

Modifying the WebPart Itself

First, you no longer want the PropertyGridEditorPart to be able to modify your DisplayText property. So, get rid of the WebBrowsable(true) attribute, thus making the PropertyGridEditor blind to this property.

For a WebPart to be custom-editable, it needs to implement the IWebEditable interface. This interface requires you to implement a property called WebBrowsableObject, which gets a reference to the WebPart control or whatever else is being edited. In most scenarios, this will be the WebPart itself. Notably, a custom user control or server control that is not a WebPart could implement this interface and be custom editable in ASP.NET 2.0. This obviously won’t work in SharePoint 2007.

The IWebEditable interface also requires you to implement a method called CreateEditorParts, which simply returns a collection of custom EditorPart controls associated with this particular WebPart, or a server control or user control that implements the IWebEditable interface. Note that I wrote collection of custom EditorPart controls. This means, you have multiple editors working against the various properties on a WebPart. In most scenarios, however, you probably want one editor per property. Having more than one will cause the framework to confuse the values and double set and reset them. This is something you should be careful of.

The implementation of the IWebEditable interface on the SimpleWebPart looks like this:

#region IWebEditable Members

EditorPartCollection IWebEditable.CreateEditorParts()
{
   List<EditorPart> editors = new List<EditorPart>();
   editors.Add(new HtmlEditor());
   return new EditorPartCollection(editors);
}

object IWebEditable.WebBrowsableObject
{
   get { return this; }
}

#endregion

That’s it! Your custom editor and your WebPart are now ready to use.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read