This works for a normal UserControl, so it should work for you:
Define the base field, and create a public property for it, with the name of the display property you wish. Include the property Properties as shown below:
private ThumbDisplay thumb = new ThumbDisplay();
[Category("Appearance"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ThumbDisplay Thumbnails
{
get { return thumb; }
set { thumb = value; }
}
Create your class for the property, with Properties as shown:
[TypeConverter(typeof(ThumbInfoConverter))]
public class ThumbDisplay
{
private int minWidth = 25;
[NotifyParentProperty(true),
RefreshProperties(RefreshProperties.Repaint)]
public int MinWidth
{
get { return minWidth; }
set { minWidth = value; }
}
private int initialWidth = 100;
[NotifyParentProperty(true),
RefreshProperties(RefreshProperties.Repaint)]
public int InitialWidth
{
get { return initialWidth; }
set { initialWidth = value; }
}
private int maxWidth = 255;
[NotifyParentProperty(true),
RefreshProperties(RefreshProperties.Repaint)]
public int MaxWidth
{
get { return maxWidth; }
set { maxWidth = value; }
}
}
}
Create the InfoConverter class for your class:
class ThumbInfoConverter : ExpandableObjectConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context,
Type t)
{
if (t == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, t);
}
public override object ConvertFrom(ITypeDescriptorContext context,
CultureInfo info,
object value)
{
if (value is string)
{
try
{
string s = (string)value;
Regex r = new Regex(@"\s*(?<min>\d+),\s*(?<initial>\d+),\s*(?<max>\s*\d+)");
Match m = r.Match(s);
if (m.Groups.Count == 4)
{
int min = Convert.ToInt32(m.Groups[1].Value);
int initial = Convert.ToInt32(m.Groups[2].Value);
int max = Convert.ToInt32(m.Groups[3].Value);
ThumbDisplay t = new ThumbDisplay();
t.MinWidth = min;
t.InitialWidth = initial;
t.MaxWidth = max;
return t;
}
}
catch { }
throw new ArgumentException("Cannot convert '" + (string)value +
"' to type ThumbDisplay \"minimumWidth, initialWidth, "+
"maximumWidth\"");
}
return base.ConvertFrom(context, info, value);
}
public override object ConvertTo(ITypeDescriptorContext context,
CultureInfo culture,
object value,
Type destType)
{
if (destType == typeof(string))
{
ThumbDisplay t = (ThumbDisplay)value;
return string.Format("{0}, {1}, {2}",
t.MinWidth,
t.InitialWidth,
t.MaxWidth);
}
return base.ConvertTo(context, culture, value, destType);
}
}
In order to provide the sort order for the subproperties yourself, overide the ExpandableObjectConverter GetProperties method:
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context,
object value,
Attribute[] attributes)
{
return TypeDescriptor.GetProperties(typeof(ThumbDisplay), attributes).Sort(new string[] { "MinWidth", "InitialWidth", "MaxWidth" });
}