Add to My Yahoo! | Google Reader or Homepage | Add to Windows Live | Add to Windows Live Alerts

Wictor Wilén

Microsoft Certified Master (MCM) - SharePoint 2010 | Microsoft Most Valuable Professional (MVP) - SharePoint Server MVP | Author

Web Part Properties - part 6 - Complex Properties

Posted at 2009-02-17 11:28 by Wictor Wilén in .NET , SharePoint , Web Parts with 5 comments.

To end my series of Web Part properties I would like to show how to store more complex values than just strings or integers. What happens if you would like to store a more complex object; an array or a coordinate etc?

Editing these properties with the standard generated interface using the WebBrowsable and Personalizable attributes will not work, since it only accepts basic types, shown in part 1. To make these properties editable you have to (almost…continue reading) create an EditorPart, shown in part 2, and control the properties in the SyncChanges and ApplyChanges methods.

Note: For more information on which basic types that can be used in the standard toolbar see the PropertyGridEditorPart documentation on MSDN.

SharePoint Designer and complex properties

If you are using SharePoint Designer to edit your Web Parts, you can manage your complex properties a little bit more. For example if you store have string array, it will not be visible in the web interface, but it can be edited in SharePoint Designer.

  1: [WebBrowsable]
  2: [Personalizable]
  3: public string[] AnArray {
  4:     get;
  5:     set;
  6: }

The property above will not be seen in the web interface but in SharePoint Designer it will look like this:

SPD

If you click on the ellipsis button you will get a dialog in which you can edit the string array.

Custom objects without EditorParts

But if you still don’t want to create your own EditorPart you can use some .NET development techniques, familiar to you who have been working a lot with WinForms.

Let’s say that we want to have a Coordinate property that we would like to use in our web part, the class should look like this:

  1: public class Coordinate {
  2:     public float Latiude;
  3:     public float Longitude;
  4:     public override string ToString() {
  5:         return this.Latiude.ToString(CultureInfo.CurrentCulture) + 
  6:                ":" + 
  7:                this.Longitude.ToString(CultureInfo.CurrentCulture);
  8:     }
  9: }

And we expose it through our web part like this:

  1:  [WebBrowsable]
  2:  [Personalizable]
  3:  public Coordinate Coordinate {
  4:     get;
  5:     set;
  6: }

This property will not be shown in the web interface and will not be editable in SharePoint Designer. Now to get this to work, editable in the web interface as well as in SPD, we have to create an implementation of the ExpandableObjectConverter class. We will override four methods so we can convert a Coordinate to and from a string representation. The string representation is implemented in the ToString() in the code above. The whole implementation of the class looks like this:

  1: public class CoordinateConverter : ExpandableObjectConverter {
  2:     public override bool CanConvertTo(ITypeDescriptorContext context, 
  3:                          System.Type destinationType) {
  4:         if (destinationType == typeof(Coordinate))
  5:             return true;
  6:         return base.CanConvertTo(context, destinationType);
  7:     }
  8:     public override object ConvertTo(ITypeDescriptorContext context, 
  9:                            CultureInfo culture, object value, 
 10:                            System.Type destinationType) {
 11:         if (destinationType == typeof(System.String) && 
 12:             value is Coordinate) {
 13:             Coordinate coord = (Coordinate)value;
 14:             return coord.ToString();
 15:         }
 16:         return base.ConvertTo(context, culture, value, destinationType);
 17:     }
 18: 
 19:     public override bool CanConvertFrom(ITypeDescriptorContext context, 
 20:                          System.Type sourceType) {
 21:         if (sourceType == typeof(string))
 22:             return true;
 23:         return base.CanConvertFrom(context, sourceType);
 24:     }
 25:     public override object ConvertFrom(ITypeDescriptorContext context, 
 26:                            CultureInfo culture, object value) {
 27:         if (value is string) {
 28:             try {
 29:                 string s = (string)value;
 30:                 string[] arr = s.Split(':');
 31:                 Coordinate coord = new Coordinate();
 32:                 coord.Latiude = float.Parse(arr[0], 
 33:                                 CultureInfo.CurrentCulture);
 34:                 coord.Longitude = float.Parse(arr[1], 
 35:                                   CultureInfo.CurrentCulture);
 36:                 return coord;
 37:             }
 38:             catch {
 39:                 throw new ArgumentException("Can not convert '" + 
 40:                           (string)value + "' to type a Coordinate");
 41:             }
 42:         }
 43:         return base.ConvertFrom(context, culture, value);
 44:     }
 45: }

To make SharePoint and SharePoint Designer aware of that we now can convert our Coordinate class to a string representation we have to set the TypeConverter attribute on our Coordinate class. The final Coordinate class should look like this:

  1: [TypeConverter(typeof(CoordinateConverter))]
  2: public class Coordinate {
  3:     public float Latiude;
  4:     public float Longitude;
  5:     public override string ToString() {
  6:         return this.Latiude.ToString(CultureInfo.CurrentCulture) + 
  7:                ":" + 
  8:                this.Longitude.ToString(CultureInfo.CurrentCulture);
  9:     }
 10: }

If we now modify our web part we will see this in the web interface, sweet huh?

Coordinate

If we try to set it to any other value than we allow in our ConvertFrom method above, then we will get a nice error:

Coordinate error

The Coordinate property can also be edited in SharePoint Designer:

Coordinate editing in SPD

Other methods

There are other ways to make your web part handle complex properties. Wesley Bakker has a nice write up on how to use JSON notation to store and edit the values.

That was all folks…

Comments and trackbacks

#  Thank you for the great series by pefferie
Screenshot from websnpr Why did you have to override ToString()? Isn't the type converted taking care of conversion to string in all cases? Also, Latitude propery is misspelled...
#  @pefferrie by Wictor
Screenshot from websnpr Hi, I did override the ToString() method to get the coordinate to show up nice in the UI like this: Lat:Lon when the ToString() method is used. I think it is a good practice to do this for custom types that have visual representation, also I use this method in the ExpandableObjectConverter to generate the string.
#  Where is Part 5 ? by Vater Abraham
Screenshot from websnpr I cannot access part 5 of all 5 parts?
#  Carpet Cleaning Tampa by Carpet Cleaning Tampa
Screenshot from websnpr Just want to say what an appreciation blog you got here! I’ve been around for quite a lot of time, but finally decided to show my appreciation of your work!
#  Painting Fairfax VA by Painting Fairfax VA
Screenshot from websnpr There are a ton of other features that make VS 2008 a worthwhile upgrade - you can experience it yourself by downloading a copy at no cost today Scott Guthrie's Blog or upgrading from MSDN.
Make a comment on this post:
Subject:  

Your name:  
Your Url:  
Note: submissions may have to be approved before being visible, so don't submit your comment multiple times.