Tuesday, 26 February 2008

Webparts in MOSS 2007 - Part 3

We might have user customisable properties within our webpart which we think could be customised during design time. Here design time means the mode when you add the webpart into the appropriate webzone from the webpart gallery. At this point, all properties which had the WebBrowsable attribute set (check out Part 1) are available for customization.

For simple properties (say integers/string etc), MOSS automatically renders the editors for you. It even figures out the enumerations and renders the appropriate listbox..all good. For properties which need customisation, say you need to list down custom values from a DB, you would need to create a custom editor class separately and map it within the webpart.

Steps
1.) Create the editor object for the webpart

a.) Create a new class deriving from EditorPart class and create any control which you would need to use by overriding the CreateChildControls(), similar to the way we created child controls for WebParts.

b.) Now listen carefully. When we think about the Editor which would be shown, there are two important data handling instances - when the editor is shown the first time, we would need to load the currently set value in the webpart and when the editor value is applied/saved, we need to save the selected value back to the webpart.


To handle these two instances, we need to override the SyncChanges() and ApplyChanges() routines. The WebPart being edited at these points is available using the WebPartToEdit property.

Thats it, the webpart editor is ready. What is remaining is linking this editor with the WebPart.

2.) Link the editor with the WebPart.
Our WebPart needs to implement the IWebEditable interface to tell MOSS that it supports custom editors such that the right editor gets shown when our webpart is selected.

IWebEditable requires one method and one get property to be implemented:

Method CreateEditorParts - Override this method to specify all the editors which you need this web part to use (havent tried with more than one). It is at this routine we add our custom editor which we just created and return the editors list.

Property WebBrowsableObject - This expects you to return the current webpart which is currently being edited. (simplest to implement I guess :) )

Once we have the above two steps done, we are nearly done with the editor. Following is a code snippet for a quick look:


public class CustomEditorWebPart : WebPart, IWebEditable
{
private string _reviewer;

public string Reviewer
{
get { return _reviewer; }
set { _reviewer = value; }
}

#region IWebEditable Members

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

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

#endregion

protected override void Render(HtmlTextWriter writer)
{
writer.Write("Reviewer : " + Reviewer);
}
}

public class ReviewerEditor : EditorPart
{
private ListBox myListBox;

public ReviewerEditor()
{
ID = "ReviewerEditor";
Title = "Edit the Reviewer";
}

protected override void CreateChildControls()
{
myListBox = new ListBox();

myListBox.Items.Add("John");
myListBox.Items.Add("Thomas");
myListBox.Items.Add("Bipin");

Controls.Add(myListBox);
}

public override bool ApplyChanges()
{
EnsureChildControls();
CustomEditorWebPart oPart = (CustomEditorWebPart) WebPartToEdit;
oPart.Reviewer = myListBox.SelectedValue;
return true;
}

public override void SyncChanges()
{
EnsureChildControls();
CustomEditorWebPart oPart = (CustomEditorWebPart) WebPartToEdit;
myListBox.SelectedValue = oPart.Reviewer;
}
}




Next time lets look at inter communication between webparts :)


No comments: