The TypeConverter class serves a particular purpose as part of the Silverlight implementation of XAML, particularly in how many attribute values are processed and converted to object values when XAML is loaded. If you write a custom class, and you want instances of your class to be created by setting XAML attribute values, you generally must write a custom TypeConverter class, and then apply a TypeConverterAttribute to your class (or properties that use that property type) that references your type converter implementation.
This topic contains the following sections.
XAML and Type Conversion of String Values
When you set an attribute value in XAML, the initial type of that value is String. Even other primitives such as Double are initially strings to a XAML processor. The conversion to other non-string primitive values or to values of named members of an enumeration is relatively straightforward because of type conversion features that are built into the XAML processor.
A XAML processor needs two pieces of information in order to process an attribute value. The first piece of information is the type of the property value that is being set. Any string that is given as an attribute value in XAML must ultimately be converted or resolved to a value that is the property's type. If the property type is a primitive, a direct conversion of the string is attempted. If the property type is an enumeration, the string is used to check for a member in that enumeration. If the property type is neither a primitive or an enumeration, then the conversion behavior of the property or type in question must be able to provide an instance of the type, or a value, based on converting the provided attribute value string.
The TypeConverter Class
If the value is not a primitive type or enumeration, and there is no markup extension usage, then there must be some means of converting a String to the appropriate value or a new instance when the XAML is processed. This is the role of the TypeConverter class.
Note: |
|---|
TypeConverter as a class can have other usages besides XAML; in the .NET Framework, TypeConverter existed as a class long before XAML existed. The Silverlight and WPF XAML processors and general XAML design both use the TypeConverter pattern for attribute value conversion because it is an existing coding pattern that fulfilled the conversion requirements when the type conversion involves a string source. |
The Silverlight implementation of TypeConverter defines two members that are relevant for converting to and from strings for XAML processing purposes:
Of these, the most important method is ConvertFrom(ITypeDescriptorContext, CultureInfo, Object). This method converts the input string to the required object type.
CanConvertFrom(ITypeDescriptorContext, Type) is a support method that can be used when a service queries the capabilities of the TypeConverter implementation. You must implement CanConvertFrom(ITypeDescriptorContext, Type) to return true for certain cases, particularly for the String type.
Implement the signatures that take ITypeDescriptorContext, rather than the signatures that do not take ITypeDescriptorContext. This implementation pattern is consistent with the WPF and general .NET Framework pattern for implementing a TypeConverter, and these are the signatures that the XAML processor will call, although it may do so passing fixed values for ITypeDescriptorContext or CultureInfo in some cases. For the non-ITypeDescriptorContext signatures, your implementation should call the base implementation.
Silverlight 3 does not use ConvertTo (and CanConvertTo) because it does not incorporate a native serialization that uses a type converter for serializing from XAML. You should still consider implementing ConvertTo (and CanConvertTo) as a best practice for completing the wider interoperation functionality of your converter class.
Implementing a Type Converter
Implementing ConvertFrom
To be usable as a TypeConverter implementation that supports XAML, the ConvertFrom(ITypeDescriptorContext, CultureInfo, Object) method for that converter must accept a string as the value parameter. If the string is in valid format, and can be converted by the TypeConverter implementation, then the returned object must support a cast to the type expected by the property. Otherwise, the ConvertFrom(ITypeDescriptorContext, CultureInfo, Object) implementation must return null.
Each TypeConverter implementation can have its own interpretation of what constitutes a valid string for a conversion.
Note: |
|---|
Do not use the curly brace characters, particularly {, as a possible element of your string format. These characters are reserved as the entry and exit for a markup extension sequence. |
Implementing CanConvertFrom
Applying the TypeConverterAttribute
In order for your custom type converter to be used as the acting type converter for a custom class, you must apply the TypeConverterAttribute to your class definition. The ConverterTypeName that you specify through the attribute must be the type name of your custom type converter. With this attribute applied, when a XAML processor handles values where the property type uses your custom class type, it can input strings and return object instances. Rather than a class, you can apply TypeConverterAttribute to an interface, although this is less common.
You can also provide a type converter on a per-property basis. Instead of applying a TypeConverterAttribute to the class definition, apply it to a property definition (the main definition, not the get/set implementations within it). The type of the property must match the type that is processed by your custom type converter. With this attribute applied, when a XAML processor handles values of that property, it can process input strings and return object instances. The per-property type converter technique is particularly useful if you choose to use a property type where you cannot control the class definition and cannot apply a TypeConverterAttribute to the class.
TypeConverterAttribute and Subclasses
If you apply a TypeConverterAttribute to a class, then derive from that class and use the derived class type as the specific property type, TypeConverterAttribute behavior does not inherit. You must reapply another TypeConverterAttribute to the specific class definition or change the property type to be the base type. The XAML parser looks for exact type matches of property type when determining if a type converter is available, whereas by normal rules of inheritance you can provide subclasses or superclasses for the actual value. In contrast, when TypeConverterAttribute is applied to individual properties, the property preserves the conversion behavior if the property-owning type is subclassed, so long as the original property is not shadowed.
Reference
Concepts