Edit this page

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;
     }
 }
Public Class Club

    Private m_name As String
    Private m_captain As Player

    Public Property Name() As String
        Get
            Return Me.m_name
        End Get
        Set(value As String)
            If value <> Me.m_name Then
                Me.m_name = value
            End If
        End Set
    End Property

    <TypeConverter(GetType(PlayerTypeConverter))> _
    Public Property Captain() As Player
        Get
            Return m_captain
        End Get
        Set(value As Player)
            m_captain = value
        End Set
    End Property

    Public Sub New()
    End Sub

    Public Sub New(name As String, captain As Player)
        Me.m_name = name
        Me.m_captain = captain
    End Sub
End Class


Public Class Player

    Private m_name As String
    Private m_height As Double

    Public Property Name() As String
        Get
            Return Me.m_name
        End Get
        Set(value As String)
            If value <> Me.m_name Then
                Me.m_name = value
            End If
        End Set
    End Property

    Public Property Height() As Double
        Get
            Return Me.m_height
        End Get
        Set(value As Double)
            If value <> Me.m_height Then
                Me.m_height = value
            End If
        End Set
    End Property

    Public Sub New()
    End Sub

    Public Sub New(name As String, height As Double)
        Me.m_name = name
        Me.m_height = height
    End Sub
End Class

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" });
     }
 }
Public Class PlayerTypeConverter
    Inherits TypeConverter
    Public Overrides Function GetStandardValuesSupported(context As ITypeDescriptorContext) As Boolean
        Return True
    End Function

    Public Overrides Function GetStandardValuesExclusive(context As ITypeDescriptorContext) As Boolean
        Return True
    End Function

    Public Overrides Function GetStandardValues(context As ITypeDescriptorContext) As StandardValuesCollection

        Return New StandardValuesCollection(New String() {"Mark Wright", "Ian Rush", "John Barnes", "Paul Ince", "Jamie Redknapp", "Sami Hyypia", _
            "Steven Gerrard ", "Jordan Henderson"})
    End Function
End Class

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);
         }
     }
 }
Public Class PlayerTypeConverter1
    Inherits TypeConverter
    Private Const inchesToCentimetres As Double = 2.54
    Private Const centimetresToInches As Double = 0.3937008

    Public Overrides Function CanConvertFrom(context As ITypeDescriptorContext, sourceType As Type) As Boolean
        If sourceType = GetType(String) Then
            Return True
        End If

        Return MyBase.CanConvertFrom(context, sourceType)
    End Function

    Public Overrides Function CanConvertTo(context As ITypeDescriptorContext, destinationType As Type) As Boolean
        If destinationType = GetType(String) Then
            Return True
        End If

        Return MyBase.CanConvertTo(context, destinationType)
    End Function

    Public Overrides Function ConvertFrom(context As ITypeDescriptorContext, culture As CultureInfo, value As Object) As Object
        If Not (TypeOf value Is String) Then
            Return MyBase.ConvertFrom(context, culture, value)
        End If

        Dim val As String = DirectCast(value, String)

        Dim measure As String = val.Substring(val.Length - 2, 2).ToLower()
        Dim dispValue As String = val.Substring(0, val.Length - 2)
        Dim disp As Double = Double.Parse(dispValue)

        If measure.ToLower() = "ft" Then
            Return disp
        Else
            Return disp * centimetresToInches
        End If
    End Function

    Public Overrides Function ConvertTo(context As ITypeDescriptorContext, culture As CultureInfo, value As Object, destinationType As Type) As Object
        If Not (destinationType = GetType(String)) Then
            Return MyBase.ConvertTo(context, culture, value, destinationType)
        End If

        Dim regionInfo As New RegionInfo(culture.LCID)
        Dim metric As Boolean = regionInfo.IsMetric

        If metric Then
            Return String.Format("{0:N2}cm", TryCast(value, Player).Height)
        Else
            Dim inches As Double = TryCast(value, Player).Height * inchesToCentimetres

            Return String.Format("{0:F1}ft", inches)
        End If
    End Function
End Class

Figure 2: Culture-aware TypeConverter

culture-aware typeconverter culture-aware typeconverter

See also

Was this article helpful? Yes No

Give article feedback

Tell us how we can improve this article

Dummy