Project Description

Enhanced Webpart is a SharePoint webpart with enhanced properties editor. It allows you display and edit properties of most common types, and provides easy way to add custom controls to display your own types in webpart properties editor.

Also, this project contains localization classes, which will help you localize your project.

 

Elementary Example

public class EnhancedWebPartTest : EnhancedWebPart
{

    [Personalizable(PersonalizationScope.Shared),
     EnhancedWebPartProperty(true),
     WebBrowsable(false),
     WebDisplayName("Simple property")]
    public string SimpleProperty { get; set; }

}

So, what you need to do to extend your webpart, is to inherit your webpart class from EnhancedWebPart, and to mark appropriate properties with [EnhancedWebPartProperty(true)] attribute.

Also, you need to set [WebBrowsable(false)] attribute to the properties, to prevent each property from displaying in standard webpart property editor.

After deploying, you will see the property in "Preferences" editor part:

Elementary sample

 

More Complex Example

EnhancedWebPart contains several "DisplayableClasses", which allow you to show different property types in WebPart Property Editor.

You can use simple types, such as int, string and bool, or you can add your own, more complex, displayable classes.

OOTB, EnhancedWebPart provides DisplayableSPUser class, which allows display SharePoint People Picker page for picking the SPUser object.

Let's look at the code:

    public class EnhancedVisualWebPart : EnhancedWebPart
    {

        [Personalizable(PersonalizationScope.Shared),
        EnhancedWebPartProperty(true),
        WebBrowsable(false),
        WebDisplayName("Text"),
        Category("Preferences")]
        public string Text { get; set; }

        [Personalizable(PersonalizationScope.Shared),
        EnhancedWebPartProperty(true),
        WebBrowsable(false),
        WebDisplayName("check this!"),
        Category("Preferences")]
        public bool CheckThis { get; set; }

        [Personalizable(PersonalizationScope.Shared),
        EnhancedWebPartProperty(true),
        WebBrowsable(false),
        WebDisplayName("SPUser sample property"),
        Category("Preferences")]
        public SPUser SPUserSample { get; set; }

    }

And here is the result:

People picker looks like this:

People Picker

 

Localization Example

You can use some localization classes from EnhancedWebPart.Localization namespace, for localizing attributes, such as property name and property description.

Also, you can create localized drop down properties (SharePoint web part property mechanics does not allow this).

Sample code:

        [Personalizable(PersonalizationScope.Shared),
        EnhancedWebPartProperty(true),
        WebBrowsable(false),
        LocalizedWebDisplayName("SimplePropertyName", "Resource1"),
        LocalizedDescription("SimplePropertyDescription", "Resource1"),
        Category("Localization")]
        public int SimpleProperty { get; set; }

        [Personalizable(PersonalizationScope.Shared),
        EnhancedWebPartProperty(true),
        WebBrowsable(false),
        LocalizedWebDisplayName("SimplePropertyName", "Resource1"),
        LocalizedDescription("SimplePropertyDescription", "Resource1"),
        Category("Localization")]
        public DropDownEnum DropDownProperty { get; set; }

 DropDownEnum is simple localized enum:

    public enum DropDownEnum
    {
        [LocalizedDescription("DropDownPropertyValue0", "Resource1")]
        zero,
        [LocalizedDescription("DropDownPropertyValue1", "Resource1")]
        one,
        [LocalizedDescription("DropDownPropertyValue2", "Resource1")]
        two,
        [LocalizedDescription("DropDownPropertyValueMany", "Resource1")]
        many
    }

 Here is the result:

 

Create Custom Displayable Class

You can easily create your own displayable classes and plug them into your EnhancedWebPart descendent.

For instance, consider you have Filter setting in your webpart. For filtering, you need to pick filter type and filter value.

The filter type could be either Equals, or Contains. And the filter value is a simple string.

So, you can create two properties for the web part, but they will look not very nice... Another way - is to create simple displayable class.

First, let's create data class:

    public class FilterSetting
    {
        public FilterType Type;
        public string Value;
    }

 FilterType enum contains only two values:

    public enum FilterType
    {
        Contains,
        Equals
    }

 Last, we should create the DisplayableFilterSetting class, and implement the IDisplayableClass interface:

First method to implement is IsAppliableType. Here we need return true, if the property class is equal to our FilterSetting class:

    public bool IsAppliable(Type propertyType)
    {
        return propertyType == typeof(FilterSetting);
    }

The next question you need to answer - IsControlInHeaderSection(). For most displayable classes this method should return false, and true only for checkbox-like controls, when property title is placed after the control.

    public bool IsControlInHeaderSection()
    {
        return false;
    }

Now - the main method, which will create the custom control for our displayable class.

In our case, we will add a Panel with DropDownList and TextBox.

        public System.Web.UI.Control CreateControl()
        {
            Panel panel = new Panel();
            DropDownList ddl = new DropDownList();
            ddl.Items.Add("Contains");
            ddl.Items.Add("Equals");
            panel.Controls.Add(ddl);
            TextBox txt = new TextBox();
            panel.Controls.Add(txt);

            return panel;
        }

Next we will implement two methods: one is filling the control with specified value; and the other is fetching the value from control.

Control is the same as we created in previous method, so, in our case it is the Panel with two inner controls. And the value is the FilterSetting class instance.

    public void SetControlValue(System.Web.UI.Control control, object value)
    {
        Panel panel = (Panel)control;
        DropDownList ddl = (DropDownList)panel.Controls[0];
        TextBox txt = (TextBox)panel.Controls[1];

        FilterSetting filterSetting = (FilterSetting)value;

        txt.Text = filterSetting.Value;
        ddl.SelectedIndex = (int)filterSetting.Type;
    }

    public object GetControlValue(System.Web.UI.Control control)
    {
        Panel panel = (Panel)control;
        DropDownList ddl = (DropDownList)panel.Controls[0];
        TextBox txt = (TextBox)panel.Controls[1];

        FilterSetting filterSetting = new FilterSetting();
        filterSetting.Type = (FilterType)ddl.SelectedIndex;
        filterSetting.Value = txt.Text;

        return filterSetting;
    }

Easy, isn't it?

For some MEF magic, we need mark our class with MEF Export attribute: [Export(typeof(IDisplayableClass))]. You will need reference MEF assembly to do this, you can grab it from the EnhancedWebPart project folder.

Now, when the displayable class is ready, we can use FilterSetting property in our web part.

    [Personalizable(PersonalizationScope.Shared),
    EnhancedWebPartProperty(true),
    WebBrowsable(false),
    WebDisplayName("Filter"),
    Category("Preferences")]
    public FilterSetting Filter { get; set; }

If you want to place your displayable classes in separate assembly, you will need provide information about it to EnhancedWebPart. We can do this, overriding GetCompositionAssemblies() method:

    protected override IEnumerable<Assembly> GetCompositionAssemblies()
    {
        return new Assembly[] { Assembly.GetAssembly(typeof(DisplayableFilterSetting)) };
    }

Ok, now all is ready, and we can deploy our project!

Last edited Apr 2, 2011 at 2:37 PM by omlin, version 26