A A A Font Size

Pearls of MOSSy Wisdom

How to get EditorParts working in your WebParts

EditorParts are, essentially, Webpart Properties taken to the next level.  If you look at Webpart Properties, you have a very limited subset of forms they can take.  You have TextBoxes (string type), CheckBoxes (Boolean type), and simple drop-down lists (Enum type).  But what if you need a TextArea?  What if you need, as my example will show, a dynamic dropdown?  Webpart Paroperties (alone) cannot provide you with a solution.  This is where EditorParts come in. 
 
EditorParts are really special WebParts.  When you use them, they will be built as a seperate class parallel to your webpart's class.  When you impliment an EditorPart, instead of it appearing as a true webpart, it will appear in the EditorPane (dind't see THAT one coming, did you?).  This allows you to program the display and actions of the variable settings of your webpart. 
 
So here's my situation to give some context to my post:  I am writing a webpart that will allow any list from anywhere in a site collection to be viewed on any page.  While that isn't hard to do, selecting the list and view is a bit cumbersome.  I could just do webpart properties that make the user type in the Site URL, the List Name, and the View Name and then click OK to get their list displayed.  Well, I could, but nobody would use it.  Most users of SharePoint don't really know where to find any of that information, so another method had to be found.  In my case, providing two dropdown lists (one for all sites and the other filled in with the selected site's Lists/Libaries and Views) that were dynamically filled based on user selections would be a good thing.  So that meant I had to learn me some EditorPart goodness.
 
Three sources I used to get started that are worth mentioning:
 
2) Sahil Malik as another good post at: http://www.developer.com/net/asp/print.php/3627871
 
3) Ted's WSS book.  If you are a developer and you don't yet have it, get Ted Pattison's book: Inside Microsoft Windows SharePoint Services 3.0.  It will make your life easier.
Now, all three sources are good primers for the part.  All three did a good job of explaining the concept, but I found the execution to be a bit lacking for what I needed to do.  So I'm gonna fix that (I hope).
 

Ok.  So how to proceed?  First, you need to write your main webpart with a property. 

public class SiteListViewer : System.Web.UI.WebControls.WebParts.WebPart, IWebEditable
{
    private string _myEditorPartValue = "";
    [Personalizable(true), WebBrowsable(false)]
    public string myEditorPartValue
    {
        get { return _myEditorPartValue; }
        set { _myEditorPartValue = value; }
    }
    protected override void Render(HtmlTextWriter writer)
    {
        writer.Write(myReturnedValue);
    }
    EditorPartCollection IWebEditable.CreateEditorParts()
    {
        List<EditorPart> editors = new List<EditorPart>();
        editors.Add(new ListViewPicker());
        return new EditorPartCollection(editors);
    }
    object IWebEditable.WebBrowsableObject
    {
        get { return this; }
    }
}
Note there are a few new things in this webpart. 
1) The use of the IWebEditable interface. 
 
2) There are two new functions: EditorPartCollection IWebEditable.CreateEditorParts() and object IWebEditable.WebBrowsableObject.  These are what construct the EditorPart. 
 
3) The CreateEditorParts funcion.  "editors" is an array.  This means that you can add as many EditorParts as you want to the webpart.  My example uses one, but you can have as many as you need.

Now what we have our host webpart, we will need to create a new class inside the assembly.
public class ListViewPicker : EditorPart
{
    private HtmlSelect _selSelectBox;
    private string _selectedValue = "";
    [Personalizable(true), WebBrowsable(false)]
    public string selectedValue
    {
        get { return _selectedValue; }
        set { _selectedValue = value; }
    }
    public ListViewPicker()
    {
        this.ID = "ViewPicker";
        this.Title = "I have a title!";
    }
    protected override void CreateChildControls()
    {
        _selSelectBox = new HtmlSelect();
        _selSelectBox.ID = "_selSelectBox";
        Controls.Add(_selSelectBox);
    }
    protected override void Render(HtmlTextWriter writer)
    {
        writer.Write("Label:.<BR>");
        _selSelectBox.RenderControl(writer);
    }
    public override bool ApplyChanges()
    {
        EnsureChildControls();
        SiteListViewer _part = WebPartToEdit as SiteListViewer;
        _part.myEditorPartValue = _selSelectBox.Items[_selSelectBox.SelectedIndex].Value.ToString();
        return true;
    }
    public override void SyncChanges()
    {
        SiteListViewer _part = WebPartToEdit as SiteListViewer;
        EnsureChildControls();
        selectedValue = _part.myEditorPartValue;
        //Call Function(s) to populate the _selSelectBox control here
    }
}
Ok.  Here's where we need to break down a few things.  Note the following:
1) This class is not a Webpart, but rather an EditorPart.
 
2) There is a constructor in this class.  In it be sure to set the ID.  I haven't tested the theory, but blogs posts have said that while this is not required in ASP.Net pages, it is in SharePoint.  But it's also good form.  So do it.  Yeah.  Do it or I'll tell on you.
 
3) Render doesn't have to be overrided here.  But if you don't override Render, your controls will appear with no formatting in the order they were added to the Controls array.  Not pretty.
 
4) ApplyChanges.  This is one of two essential functions in the class.  ApplyChanges tells the host webpart what value is being passed back to it.  It is called when a user clicks OK or Apply in the Editor Pane.
 
Note the line:
    SiteListViewer _part = WebPartToEdit as SiteListViewer;
 
Here, you create an reference to your host webpart.  WebPartToEdit comes with the EditorPart and gives you the reference to the host.  But you must cast it as the classname of the host.  This is what threw me off at first.  Here, it's a SiteListViewer as that is the name of my host webpart.  Once you have this, you can access the public properties of the host part and thus pass values. 
 
There is no Update command as the SPWebPartManager takes care of that. 
 
Also note the "return true;" line.  You can establish logic here to validate values.  By returning false, you keep the OK from confirming the data.  It will display a generic message.  I haven't worked out how to pass specific error messages yet.
 
5) SyncChanges.  This is the function that takes the value stored in the host and passes it back to the webpart when it is created.  This is also where you will need to put in any code that will populate your control.  This is where I put the code call to dynamically fill the dropdown with the SubSite list.
That's it.  Compile and deploy as usual.  The EditorPart class does not have to be included in the web.config's SafeControls section as it is only used as part of the host webpart. 
 
So, now, when you Modify the webpart, you'll have, at the top of the Editor Pane, your custom editor control.  I used a DropDown control.  But you can change that to anything.  I've seen examples of Radio Buttons and TextAreas.  I wouldn't be suprised if any HTML control can be added.
 

As for the webpart that is an "Any Site" List Viewer.  I will try to get that posted in my blog section here soon.
You must sign in to rate content.
(Unrated)

Comments

RE: How to get EditorParts working in your WebParts


Great post!

Unfortunatly I think you have an error in the main class, at line
 writer.Write(myReturnedValue);

I think you mean
 writer.Write(_myEditorPartValue);

I've just manage to change the value of a control in the webpart, through the editor! Thanks a lot.

Have you managed to create dropdownlists for sites and lists selection?
(Can you share some code?)

Regards.
Fernando Duarte at 9/15/2009 5:11 AM
You must sign in to rate content.
(Unrated)

RE: How to get EditorParts working in your WebParts


Great post!

Unfortunatly I think you have an error in the main class, at line
 writer.Write(myReturnedValue);

I think you mean
 writer.Write(_myEditorPartValue);

I've just manage to change the value of a control in the webpart, through the editor! Thanks a lot.

Have you managed to create dropdownlists for sites and lists selection?
(Can you share some code?)

Regards.
Fernando Duarte at 9/15/2009 5:11 AM
You must sign in to rate content.
(Unrated)

RE: How to get EditorParts working in your WebParts


Great post!

Unfortunatly I think you have an error in the main class, at line
 writer.Write(myReturnedValue);

I think you mean
 writer.Write(_myEditorPartValue);

I've just manage to change the value of a control in the webpart, through the editor! Thanks a lot.

Have you managed to create dropdownlists for sites and lists selection?
(Can you share some code?)

Regards.
Fernando Duarte at 9/15/2009 5:11 AM
You must sign in to rate content.
(Unrated)

Leave a Comment

You must be logged in to post a comment.
Superstar
Tim Dobrinski
Systems Analyst II
Birmingham, AL
Tim is currently not Twittering about updating his LinkedIn profile concerning FaceBooking his MySpace Page's Status.

Search This Blog

 

© 2012 SusQtech. All rights reserved.
Powered by SharePoint Server 2007 and using the MemberToMember SharePoint Add-On for social media capabilities.