So I figured it out, here's the code if anyone's interested.
Three classes need to be added to the control: PolygonHotSpot.cs, MapPolygon.cs & and MapPolygonConverter.cs. The HotSpotCollection.cs class needs to be modified as well (not included here - pretty obvious what needs to be done though).
// PolygonHotSpot.cs
using System;
using System.ComponentModel;
using System.Web.UI;
namespace MSPress.ServerControls
{
public class PolygonHotSpot : HotSpot
{
private MapPolygon _polygon;
public PolygonHotSpot() : this(new MapPoint[0], String.Empty, String.Empty)
{
}
public PolygonHotSpot(MapPoint [] pts, string action, string toolTip) :
base(action, toolTip)
{
Pts = pts;
}
[
Category("Shape"),
DefaultValue(typeof(MapPoint), ""),
Description("The collection of points that make up the polygon"),
NotifyParentProperty(true)
]
public MapPoint []Pts
{
get
{
return ((MapPolygon)Shape).Pts;
}
set
{
((MapPolygon)Shape).Pts = value;
}
}
public override MapShape Shape
{
get
{
if (_polygon == null)
{
_polygon = new MapPolygon();
}
return _polygon;
}
}
protected override bool ShapeCreated
{
get
{
return (_polygon != null);
}
}
}
}
// MapPolygon.cs
//
//
using System;
using System.ComponentModel;
namespace MSPress.ServerControls
{
[
TypeConverter(typeof(MapPolygonConverter))
]
public class MapPolygon : MapShape
{
private MapPoint[] _pts;
public MapPolygon()
{
}
public MapPolygon(MapPoint[] pts)
{
_pts = pts;
}
[
DefaultValue(typeof(MapPoint),""),
NotifyParentProperty(true)
]
public MapPoint []Pts
{
get
{
return _pts ;
}
set
{
if (value == null)
{
throw new ArgumentNullException("value");
}
_pts = value;
}
}
public override bool IsEmpty
{
get
{
return (_pts.Length == 0);
}
}
public override string MapCoordinates
{
get
{
string strCoordinates;
strCoordinates = string.Empty;
if (_pts.Length > 0 )
{
for (int i =0; i < _pts.Length;i++)
{
strCoordinates += _pts[i].X + "," + _pts[i].Y + "," ;
}
//Strip out last comma for the string
strCoordinates = strCoordinates.Substring(0,strCoordinates.Length -1);
return strCoordinates;
}
else
return "";
}
}
protected override MapShapeName MapShapeName
{
get
{
return MapShapeName.Polygon;
}
}
public override void LoadFromString(string value)
{
if (value.Length != 0)
{
MapPolygon p = (MapPolygon)TypeDescriptor.GetConverter(typeof(MapPolygon)).ConvertFromInvariantString(null, value);
for (int i =0; i < this._pts.Length;i++)
{
this.Pts[i] = p.Pts[i];
}
}
}
public override string SaveToString()
{
return TypeDescriptor.GetConverter(typeof(MapPolygon)).ConvertToInvariantString(this);
}
}
}
// MapPolygonConverter.cs
using System;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Globalization;
using System.Reflection;
namespace MSPress.ServerControls
{
public class MapPolygonConverter : MapShapeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value == null)
{
return new MapPolygon();
}
if (value is string)
{
string s = (string)value;
if (s.Length == 0)
{
return new MapPolygon();
}
string[] parts = s.Split(culture.TextInfo.ListSeparator[0]);
if (parts.Length == 0)
{
throw new ArgumentException("Invalid MapPolygon", "value");
}
TypeConverter intConverter = TypeDescriptor.GetConverter(typeof(Int32));
MapPoint[] pts;
pts = new MapPoint[parts.Length/2];
int j = 0;
for (int i=0; i<parts.Length/2;i++)
{
int X = (int)intConverter.ConvertFromString(context, culture, parts[j]);j++;
int Y = (int)intConverter.ConvertFromString(context, culture, parts[j]);j++;
pts[i] = new MapPoint(X,Y);
}
return new MapPolygon(pts);
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (value != null)
{
if (!(value is MapPolygon))
{
throw new ArgumentException("Invalid MapPolygon", "value");
}
}
if (destinationType == typeof(string))
{
if (value == null)
{
return String.Empty;
}
MapPolygon poly = (MapPolygon)value;
if (poly.IsEmpty)
{
return String.Empty;
}
TypeConverter intConverter = TypeDescriptor.GetConverter(typeof(Int32));
int count = poly.Pts.Length;
string[] strConvert = new string[2*count];
int j = 0;
for (int i = 0;i<poly.Pts.Length;i++)
{
strConvert[j] = intConverter.ConvertToString(context, culture, poly.Pts[i].X);j++;
strConvert[j] = intConverter.ConvertToString(context, culture, poly.Pts[i].Y);j++;
}
return String.Join(culture.TextInfo.ListSeparator,strConvert);
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
}