TypeConverter Support
In certain cases, RadPropertyGrid is used for displaying and editing properties of custom data type. By default, in such scenarios the control will display the custom type as a string. RadPropertyGrid provides TypeConverter support, meaning that this behavior can be modified by defining a custom TypeConverter. The main methods that are usually utilized when implementing a custom TypeConverter are listed below.
-
Override the CanConvertFrom method that specifies which type the converter can convert from.
-
Override the ConvertFrom method that implements the conversion.
-
Override the CanConvertTo method that specifies which type the converter can convert to.
-
Override the ConvertTo method that implements the conversion.
More information on implementing a TypeConverter can be found in MSDN: How to: Implement a Type Converter.
Defining the Business Object
Demonstrating the TypeConverter mechanism in the scope of RadPropertyGrid will require an object which has a property of custom data type. This section will cover the process of defining them.
The example will use a Club object which has a Captain property of type Player.
Example 1: Defining the business object
public class Club
{
private string name;
private Player captain;
public string Name
{
get { return this.name; }
set
{
if (value != this.name)
{
this.name = value;
}
}
}
[TypeConverter(typeof(PlayerTypeConverter))]
public Player Captain
{
get { return captain;}
set
{
captain = value;
}
}
public Club()
{
}
public Club(string name, Player captain)
{
this.name = name;
this.captain = captain;
}
}
public class Player
{
private string name;
private double height;
public string Name
{
get { return this.name; }
set
{
if (value != this.name)
{
this.name = value;
}
}
}
public double Height
{
get { return this.height; }
set
{
if (value != this.height)
{
this.height = value;
}
}
}
public Player()
{
}
public Player(string name, double height)
{
this.name = name;
this.height = height;
}
}Display a Predefined List of Values for a Property with TypeConverter
As of R1 2017, the TypeConverter mechanism of RadPropertyGrid provides support for a standard set of values that can be picked from a predefined list. This can be done through overriding the GetStandardValuesSupported method.
Example 2: Defining a TypeConverter providing a default set of values
public class PlayerTypeConverter : TypeConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection(new string[] { "Mark Wright", "Ian Rush", "John Barnes",
"Paul Ince", "Jamie Redknapp", "Sami Hyypia", "Steven Gerrard ", "Jordan Henderson" });
}
}If EditorAttribute is set to a specific property with a set TypeConverter the EditorAttribute is with lower priority - a default set of values will be visualized if the GetStandardValuesSupported is overridden instead of an editor.
Figure 1: TypeConverter providing a default set of values

Culture-aware TypeConverter
In this section, the definition of a culture aware TypeConverter will be demonstrated. The support for it is added as of R1 2017. For this purpose, the Height property of the Player object will be used.
Example 3: Defining a culture aware TypeConverter
public class PlayerTypeConverter1 : TypeConverter
{
private const double inchesToCentimetres = 2.54;
private const double centimetresToInches = 0.3937008;
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 is string))
{
return base.ConvertFrom(context, culture, value);
}
string val = (string)value;
string measure = val.Substring(val.Length - 2, 2).ToLower();
string dispValue = val.Substring(0, val.Length - 2);
double disp = double.Parse(dispValue);
if (measure.ToLower() == "ft")
{
return disp;
}
else
{
return disp * centimetresToInches;
}
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (!(destinationType == typeof(string)))
{
return base.ConvertTo(context, culture, value, destinationType);
}
RegionInfo regionInfo = new RegionInfo(culture.LCID);
bool metric = regionInfo.IsMetric;
if (metric)
{
return string.Format("{0:F0}cm", (value as Player).Height);
}
else
{
double inches = (value as Player).Height * inchesToCentimetres;
return string.Format("{0:F0}ft", inches);
}
}
}Figure 2: Culture-aware TypeConverter
