Quantcast
Channel: Umair's Blog » .NET
Viewing all articles
Browse latest Browse all 3

Creating a Custom XAML TypeConverter

0
0

TypeConverters provide a means of converting a String to the appropriate .NET type or a new instance when XAML is processed. I’ve already looked at how the XAML parser searches for TypeConverters (XAML and TypeConverters ) Now let’s take a look at how to create our custom TypeConverter.

At a minimum, for a class to conform to the Silverlight implementation of TypeConverters it must be a subclass of the TypeConverter class and must contain the following two members for converting from strings for XAML processing:

1. The class must override the CanConvertFrom(…) method:

public virtual bool CanConvertFrom(
    ITypeDescriptorContext context,
    Type sourceType
)

It must return true when the sourceType parameter is String, and otherwise defer to the base implementation.

2. The class must provide an implementation of ConvertFrom(...) method:

public virtual Object ConvertFrom(
    ITypeDescriptorContext context,
    CultureInfo culture,
    Object value
)

To be usable as a TypeConverter implementation that supports XAML, this method must accept a string as the value parameter. If the string is valid, the returned object must support a cast to the type expected by the property. Otherwise it must return null.

The .NET specification for TypeConverters also contains two more key methods, which are ConvertTo and CanConvertTo. However, Silverlight 3 (as well as Silverlight 4 Beta) does not use ConvertTo and CanConvertTo, so you can skip these if your TypeConverter is for Silverlight's XAML processing. It's still a good idea to implement these two as a best practice for completing the wider interoperation functionality of the converter class.

 

Putting it all together: An Example:

Suppose I have a custom Silverlight control called WidgetControl, that has a property called WidgetHeight. If you need to see how to add custom controls to your project, please check out my post "Adding a Custom Silverlight Control". I use this control in my XAML file as follows:

<Custom:WidgetControl x:Name="widget" WidgetHeight="2 inches"/>

Somehow I need to handle the case where the unit of length is specified for the value of WidgetHeight property. This is done via a custom XAML TypeConverter called CustomLengthConverter, which is shown below:

    public class CustomLengthConverter : TypeConverter
    {
        public override bool CanConvertFrom(
            ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
            {
                return true;
            }
            return base.CanConvertFrom(context, sourceType);
        }


        public override object ConvertFrom(ITypeDescriptorContext
                context, CultureInfo culture, object value)
        {

            if (value == null)
            {
                return new Double();
            }
            if (value is string)
            {
                string s = (string)value;
                if (s.Length == 0)
                {
                    return new Double();
                }

                string[] arguments = s.Split(' ');
                if (arguments.Length != 2)
                {
                    throw new ArgumentException("Value must have the format <number length_unit>");
                }
                else
                {
                    return InternalParseInput(arguments[0]);
                }
            }

            return base.ConvertFrom(context, culture, value);
        }


        public Double InternalParseInput(String inputString)
        {
            Double doubleValue;

            try
            {
                doubleValue = Double.Parse(inputString);
            }
            catch(Exception){
                doubleValue = new Double();
            }

            return doubleValue;
        }
    }

Finally, in my WidgetControl class, I explicitly specify that the WidgetHeight property should use the CustomLengthConverter defined above:

    public partial class WidgetControl : UserControl
    {
	...

        [TypeConverter(typeof(CustomLengthConverter))]
        public Double WidgetHeight
        {
	   ...
        }
    }

So every time my XAML for WidgetControl's WidgetHeight property is parsed, the parser uses the CustomLengthConverter to convert the property value from String to the appropriate .NET type (Double)



Viewing all articles
Browse latest Browse all 3

Latest Images

Trending Articles





Latest Images