Blog

Custom Editor Parts in SharePoint 2010

Custom Editor Parts in SharePoint 2010

Creating custom web parts for SharePoint 2010 is relatively simple, as is creating basic configuration options which can be edited in the properties panel. However, as you advance in your understanding of SharePoint and custom web part creation, you inexorably run in to the problem of creating rich, custom configuration capabilities for your web part which go far beyond the basic configuration capabilities. Well, custom configuration is not all that difficult, and in this blog I am going to show you how to create custom editor parts for your custom web part.

Before continuing, it may be helpful to review how to create basic configuration options for your web parts. I covered this topic in a previous blog post (link). It is always best to do things the simplest way possible and if this satisfies the requirements of your project I would highly recommend sticking to this method.

All custom visual web parts in SharePoint 2010 have three main files which implement the solution: the main class file for the custom web part (in this example WebPart1.cs), and the two files that comprise the user control which the custom web part renders (in this example WebPart1UserControl.ascx and the code behind file WebPart1UserControl.ascx.cs). In this example we will be focusing entirely on the custom web part class file WebPart1.cs plus a new cs file to hold the custom editor part which we will create.

This example covers a common scenario. Let’s say we need to populate a drop down list with values which we calculate or ascertain in some manner (database query etc.). It is impossible to do this with the basic configuration methodologies so we will need a custom editor part. The first thing we need to do is create a new cs class file in the visual web part folder name WebPartEditorPart1.cs. The skeleton code for an editor part (that this article is going to use) is as follows:

namespace WebPartLibrary.WebPart1
{
   [AspNetHostingPermission(SecurityAction.Demand, Level   
    AspNetHostingPermissionLevel.Minimal)]
    class WebPartEditorPart : EditorPart
    {
        ///<summary>
        /// Saves configuration back to web part
        ///</summary>
        ///<returns>true</returns>
        public override bool ApplyChanges()
        {
            return true;
        }
 
        ///<summary>
        /// Loads configuration, method is unused
        ///</summary>
        public override void SyncChanges()
        {
        }
 
        ///<summary>
        /// Create controls for tool part
        ///</summary>
        protected override void CreateChildControls()
        {
        }
 
        ///<summary>
        /// Create the HTML for the tool part
        ///</summary>
        ///<param name="writer">The HTML writer to output HTML in to</param>
        protected override void RenderContents(HtmlTextWriter writer)
        {
        }
    }
}

All methods shown above are overridden methods of the EditorPart base class. A brief explanation of the purpose of each method is included in the method header. For more verbose explanations please refer to the MSDN article on the EditorPart class (link). We will modify this template so that we have a dropdown box, a text box, and a button for the user to click:

namespace WebPartLibrary.WebPart1
{
    [AspNetHostingPermission(SecurityAction.Demand, Level    
     AspNetHostingPermissionLevel.Minimal)]
    class WebPartEditorPart : EditorPart
    {
        #region Private Controls
        private DropDownList _ddl;
        private TextBox _txt;
        private Button _btn;
        #endregion
 
        #region Protected Attributes
        protected bool _bInit = false;
        #endregion


        ///<summary>
        /// Saves configuration back to web part
        ///</summary>
        ///<returns>true</returns>
        public override bool ApplyChanges()
        {
            
           // Saves configuration back to web part
            WebPart1 wp = (WebPart1)WebPartToEdit;
            wp.SelectedValue = _ddl.SelectedValue;
            wp.TextValueToStore = _txt.Text;
           
            return true;
        }
 
        ///<summary>
        /// Load configuration, method is unused
        ///</summary>
        public override void SyncChanges()
        {
           // TODO: add code if needed
        }
 
        ///<summary>
        /// Create controls for tool part
        ///</summary>
        protected override void CreateChildControls()
        {
            Controls.Clear();
 
            //create controls
            _ddl = new DropDownList() { ID = "ddl" };
            Controls.Add(_ddl);
            _txt = new TextBox() { ID = "txt" };
            Controls.Add(_txt);
            _btn = new Button() { ID = "btn", Text = "Click this button >>" };
            _btn += new EventHandler(_btn_Click);
            Controls.Add(_btn);
 
            //populate dropdown list
            //TODO: query and get an array of values - arStrings
            foreach (string sz in arStrings)
            {
            	_ddl.Items.Add(new ListItem(sz, sz));
            }


            //initialize values from SharePoint storage (by way of the WebPart's class)
            if (_bInit == true)
            {
                _bInit = false;
		_ddl.SelectedValue = wp.SelectedValue;
		_txt.Text = wp.TextValueToStore;
            }

        }
 
        ///<summary>
        /// Create the HTML for the tool part
        ///</summary>
        ///<param name="writer">The HTML writer to output HTML in to</param>
        protected override void RenderContents(HtmlTextWriter writer)
        {
            writer.Write("Select a value from the drop down list");
            writer.WriteBreak();
            _ddl.RenderControl(writer);
            writer.WriteBreak();
            writer.Write("Type in a string for the text box");
            writer.WriteBreak();
            _txt.RenderControl(writer);
            writer.WriteBreak();
            _btn.RenderControl(writer);
        }
 
        ///<summary>
        /// btn click handler
        ///</summary>
        ///<param name="sender">Sender</param>
        ///<param name="e">Event Args</param>
        protected void _btn_Click(object sender, EventArgs e)
        {
           //TODO: add code for the btn click event if needed
        }
    }
}

That’s all there is to it to create a custom editor part. It’s pretty straightforward. What is nice is that once your editor part is properly added via the your custom web part class file (in this example: WebPart.cs) SharePoint will take care of storing the configured values in the SharePoint database, and will even take care of loading the values from the SharePoint database into your web part class. This leaves you with only having to set the controls in your editor part to the correct values! Once the editor part is completed, the next step in development is setting up your custom web part class file to add the editor part to SharePoint:

namespace DMCChartingLibrary.WebPart1
{
    [ToolboxItemAttribute(false)]
    public class WebPart1 : WebPart
    {
 
        #region Public Attributes
        public string SelectedValue;
        public string TextValue;
        #endregion
 
        #region Public Non Web-Browsable Attributes
        [Personalizable(), WebBrowsable(false)]
        public string SelectedValueOfDDL
        {
            get { return SelectedValue; }
            set { SelectedValue = value; }
        }
        [Personalizable(), WebBrowsable(false)]
        public string TextValueToStore
        {
            get { return TextValue; }
            set { TextValue = value; }
        }
        #endregion
 
        ///<summary>
        /// Constructor
        ///</summary>
        public WebPart1 () : base()
        {
            //TODO: set defaults if needed
        }
 
        // Visual Studio might automatically update this path
        // when you change the Visual Web Part project item.
        private const string _ascxPath = @"~/_CONTROLTEMPLATES/WebPartLibrary/WebPart1/WebPart1UserControl.ascx";
 
        ///<summary>
        /// Creates the child control (the web control with all functionality)
        ///</summary>
        protected override void CreateChildControls()
        {
            //load main web control
            WebPart1UserControl control = (WebPart1UserControl)Page.LoadControl(_ascxPath);
            Controls.Add(control);
        }
       
        ///<summary>
        /// Needed to add custom editor parts to page
        ///</summary>
        ///<returns>Editor part collection containing said parts</returns>
        public override EditorPartCollection CreateEditorParts()
        {
            ArrayList alControls = new ArrayList();
            alControls.Add(new WebPartEditorPart() {ID = this.ID + "_EditorPartExample",
                                               Title = "Edit part example",
                                               ChromeState = PartChromeState.Minimized});
            EditorPartCollection epc = new EditorPartCollection(alControls);
 
            return epc;
        }
    }
}

Of special interest in the code above is the editor part property:

ChromeState = PartChromeState.Minimized

This ensures that the editor part is initially collapsed when the properties panel is opened; this is usually the preferred way of doing things so that your editor part does not initially take too much screen real estate and block users from locating the section and item they wish to change.

I hope this helps you on your way to developing compelling web parts for SharePoint 2010. At DMC, we are experts at helping our clients maximize the value of SharePoint (especially implementing SharePoint dashboards). If you feel overloaded (or over your head), don't hesitate to contact DMC to get some help with your project.

Learn more about DMC's SharePoint consulting services.

Comments

Arfath
# Arfath
I'm a newbie into Sharepoint. I tried searching for what #Dan and #Jet asked, but failed to find any help. Appreciate if any of you could share with me anything that you may have found by this time.
Jet
# Jet
I Also want to have the same effect as Dan (custom editor part will look like the Appearance, layout, etc...) and if possible can I place the custom editorpart at the bottom instead of the top?
Dan
# Dan
Is it possible to make the custom editorpart look like the OOB editorparts (Appearance, Layout, etc..) with the Expand/Collapse button on the left with the plus/minus image

Post a comment

Name (required)

Email (required)

CAPTCHA image
Enter the code shown above: