Today, I want to start new tag - “Work process”. Here I’m going to publish partial classes, fixes, small utilities, I’m building for myself or clients to help in work process. I’ll give an example: currently, I’m working on BiDi support for Silverlight 2.0 (beta 2 to RTM). During the work process, I need to write different classes, such as converters, string utilities, exception helpers etc.
© Imaginary copyright by Noel Hendrickson
So, today I’ll public general type converter for generic classes.
What is type converter?
TypeConverter is a service attribute, used to help rendering engine to convert XAML string (usually it strings) to the type, you require in your class implementation. Here an example:
In your custom class you have dependency property of type TextAlignment
public TextAlignment TextAlignment
{
get { return (TextAlignment)GetValue(TextAlignmentProperty); }
set { SetValue(TextAlignmentProperty, value); }
}
In XAML code it will be used as:
<MyControl TextAlignment=”Left”/>
But, what you’re actually transfer to your class is string “Left”, when you need enum TextAlignment.Left, how to convert it? This for we’re using type converters
Attribute usage
In order to “tell” framework to use your type converter, you should mark target property with special attribute TypeConverterAttribute. Also, you can provide default value to your property by using another attribute DefaultValueAttribute. This will looks as following:
[TypeConverter(typeof(MyTextAlignmentTypeConverter))]
[DefaultValue(TextAlignment.Left)]
public TextAlignment TextAlignment
{
get { return (TextAlignment)GetValue(TextAlignmentProperty); }
set { SetValue(TextAlignmentProperty, value); }
}
How to build type converter
In order to build type converter, all you have to do is to build your own class, derived from TypeConverter. It also can be generic class. Then, implement necessary methods, that incorporate your business logic. Like this one, converter any enum value back and forward for TypeConverterAttribute
public class EnumValueConverter<T> : TypeConverter where T:struct
{
static EnumValueConverter()
{
if (!typeof(T).IsEnum) { Exceptions.ThrowInvalidOperationException("Cannot use this type for conversion"); }
}public override bool CanConvertFrom(Type sourceType)
{
return Type.GetTypeCode(sourceType) == TypeCode.String;
}public override object ConvertFrom(object value)
{
if (value == null)
{
typeof(T).ThrowConvertFromException(value);
}
if (value is string)
{
return ConvertFromString(value as string);
}
return (T)value;
}public override object ConvertFromString(string text)
{
return (T)Enum.Parse(typeof(T), text, true);
}public override string ConvertToString(object value)
{
return Enum.GetName(typeof(T), value);
}
}
Final result
Now, when we built converter and know how to use it, we can easily set it to any DependencyProperty requires conversion from / to enum
[TypeConverter(typeof(EnumValueConverter<LineStackingStrategy>))]
public LineStackingStrategy LineStackingStrategy
{
get { return (LineStackingStrategy)GetValue(LineStackingStrategyProperty); }
set { SetValue(LineStackingStrategyProperty, value); }
}
[TypeConverter(typeof(EnumValueConverter<TextAlignment>))]
[DefaultValue(TextAlignment.Right)]
public TextAlignment TextAlignment
{
get { return (TextAlignment)GetValue(TextAlignmentProperty); }
set { SetValue(TextAlignmentProperty, value); }
}
[TypeConverter(typeof(EnumValueConverter<TextWrapping>))]
public TextWrapping TextWrapping
{
get { return (TextWrapping)GetValue(TextWrappingProperty); }
set { SetValue(TextWrappingProperty, value); }
}
We done, have a nice day and be good people.
Stay tuned for release of BiDi support for Silverlight 2.0, sponsored by Development Platform Evangelism unit of Microsoft Israel
No comments:
Post a Comment