Reputation: 1441
I need to display an object correctly in the propertygrid. my class looks like this:
public class PropertyItem
{
public PropertyDescription PropertyDescription { get; set; }
[Description("the value"), Browsable(true)]
public object Value { get; set; }
public PropertyItem(PropertyDescription propertyDescription, object value)
{
PropertyDescription = propertyDescription;
Value = value;
}
public override string ToString()
{
return this.PropertyDescription.Name + ": " + PropertyDescription.Type + ": " + Value;
}
}
Value
is of type object
and this cannot be changed.
The PropertyDescription
has the type of the Value
and this can be anything (string
, int
, bool
...)
When I set the SelectedObject
of my PropertyGrid
, the Value
is always disabled.
How would I write a TypeConverter
to convert the object
Value
to the Type
in the PropertyDescription
?
Upvotes: 3
Views: 4251
Reputation: 18013
Define a custom type converter for the property:
[TypeConverter(typeof(PropertyValueConverter))]
public object Value { get; set; }
And implement it like this:
public class PropertyValueConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
var propItem = context.Instance as PropertyItem;
return propItem != null && TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).CanConvertFrom(context, sourceType)
|| base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var propItem = context.Instance as PropertyItem;
if (propItem != null)
return TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).ConvertFrom(context, culture, value);
else
return base.ConvertFrom(context, culture, value);
}
}
This test code worked for me:
var pi = new PropertyItem(new PropertyDescription { Type = typeof(int) }, 1);
propertyGrid1.SelectedObject = pi;
Update:
To support dropdown list (eg. bool):
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
var propItem = context.Instance as PropertyItem;
if (propItem != null)
return TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).GetStandardValues(context);
else
return base.GetStandardValues(context);
}
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
var propItem = context.Instance as PropertyItem;
if (propItem != null)
return TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).GetStandardValuesSupported(context);
else
return base.GetStandardValuesSupported(context);
}
To support custom openable properties (eg. Point):
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
var propItem = context.Instance as PropertyItem;
if (propItem != null)
return TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).GetProperties(context, value, attributes);
else
return base.GetProperties(context, value, attributes);
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
var propItem = context.Instance as PropertyItem;
if (propItem != null)
return TypeDescriptor.GetConverter(propItem.PropertyDescription.Type).GetPropertiesSupported(context);
return base.GetPropertiesSupported(context);
}
Upvotes: 5