New to Telerik UI for WPF? Download free 30-day trial

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

WPF RadPropertyGrid 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

culture-aware typeconverter culture-aware typeconverter