Conversion Conversation

In Tag, you are not it I mistakenly said you need an IValueConverter so that the xaml parser could convert the string "Divide" into the enum value Operator.Divide.  (I must've been too busy trying to find a clever Parthian Shot.)

IValueConverters are used by the binding engine, and are assigned via binding markup extensions.

The OperationConverter code that I provided was not used by the xaml parser. Instead, the parser was automatically turning the string into the corresponding enum value.

So my sample code worked quite by accident, because I happened to use an enum to define my operations. What happens when I use objects instead of enums?

To find out, lets change the Operator class, and remove the enum:

public class Operator { public static Operator GetOperator(DependencyObject obj) { return (Operator)obj.GetValue(OperationProperty); } public static void SetOperator(DependencyObject obj, Operator value) { obj.SetValue(OperationProperty, value); } public static readonly DependencyProperty OperationProperty = DependencyProperty.RegisterAttached("Operator", typeof(Operator), typeof(Operator), null); } public class NotAnOperator : Operator { } public class PlusOperator : Operator { } public class MinusOperator : Operator { } public class TimesOperator : Operator { } public class DivideOperator : Operator { } public class EqualsOperator : Operator { }

then update Page.xaml:

<Button Grid.Column="3" Grid.Row="2" Content="/" Style="{StaticResource calcButtonStyle}" local:Operator.Operator="Divide" Click="ClickOperator" />

When I run the code, I get this nasty exception:

image

Wow! Catastrophic!

I am missing a converter, but not a value converter. What I need is a TypeConverter. Lets replace the OperationConverter code with OperatorConverter:

public class OperatorConverter : TypeConverter { public override object ConvertFrom(object value) { System.Diagnostics.Debug.WriteLine( "Converting '{0}' to an Operator", value.ToString()); Operator returnValue = new NotAnOperator(); if (value.GetType().Equals(typeof(System.String))) { switch ((string)value) { case "Minus": returnValue = new MinusOperator(); break; case "Plus": returnValue = new PlusOperator(); break; case "Times": returnValue = new TimesOperator(); break; case "Divide": returnValue = new DivideOperator(); break; case "Equals": returnValue = new EqualsOperator(); break; } } return returnValue; } }

and add a TypeConverter attribute to the Operator class:

[TypeConverter(typeof(OperatorConverter))] public class Operator

This time, when I run, the conversion code does get called.

Published May 19, 2008

AttachmentSize
AttachedPropertiesAndTypeConversion.zip6.12 KB