I'm trying to use a DataTriggerBehavior
from the Behaviors SDK. But it doesn't seem to work with enums... or else I'm doing something wrong.
You can assume that the DataContext
for these examples is something like this (INotifyPropertyChanged
is implemented, but I'm not going to show it here):
public class MyDataClass
{
public MyEnum ItemCommand { get; set; }
public string ItemCommandString { get; set; }
}
public enum MyEnum
{
EnumValue1
}
_Button.DataContext = new MyDataClass() { ItemCommand = MyEnum.EnumValue1,
ItemCommandString = "EnumValue1" };
Here is the code that doesn't work (trying to specify an enum value and check against the ItemCommand enum property):
<ToggleButton x:Name="_Button">
<Interactivity:Interaction.Behaviors>
<Core:DataTriggerBehavior Binding="{Binding ItemCommand}"
Value="EnumValue1">
<Core:ChangePropertyAction PropertyName="Command"
TargetObject="{Binding ElementName=_Button}"
Value="{x:Null}">
</Core:ChangePropertyAction>
</Core:DataTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</ToggleButton>
and this code (checking against an enum resource) also does not work:
<UserControl.Resources>
<local:MyEnum x:Key="_MyEnumValue">EnumValue1</local:MyEnum>
</UserControl.Resources>
<ToggleButton x:Name="_Button">
<Interactivity:Interaction.Behaviors>
<Core:DataTriggerBehavior Binding="{Binding ItemCommand}"
Value="{StaticResource _MyEnumValue}">
<Core:ChangePropertyAction PropertyName="Command"
TargetObject="{Binding ElementName=_Button}"
Value="{x:Null}">
</Core:ChangePropertyAction>
</Core:DataTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</ToggleButton>
whereas this code (checking against a string) does work:
<ToggleButton x:Name="_Button">
<Interactivity:Interaction.Behaviors>
<Core:DataTriggerBehavior Binding="{Binding ItemCommandString}"
Value="EnumValue1">
<Core:ChangePropertyAction PropertyName="Command"
TargetObject="{Binding ElementName=_Button}"
Value="{x:Null}">
</Core:ChangePropertyAction>
</Core:DataTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</ToggleButton>
What is the correct way to specify the enum value in the DataTriggerBehavior
Value
property so that this will work?
you can write a Converter:
public class MyEnumConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
MyEnum myEnumValue = (MyEnum)value;
return myEnumValue.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
And use it in XAML:
<ToggleButton x:Name="_Button">
<Interactivity:Interaction.Behaviors>
<Core:DataTriggerBehavior Binding="{Binding ItemCommand, Converter={StaticResource MyEnumConverter}}"
Value="EnumValue1">
<Core:ChangePropertyAction PropertyName="Command"
TargetObject="{Binding ElementName=_Button}"
Value="{x:Null}">
</Core:ChangePropertyAction>
</Core:DataTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</ToggleButton>
Or bind direct to the string as in your sample. Unfortunately DataTriggerBehavior in WinRT is worse that DataTrigger in Windows Phone 8
I was investigating this issue and narrowed the problem down to TypeConverterHelper
class.
TypeConverterHelper source
Apparently it doesn’t account for enum types and falls back to some logic which recreates the xaml string for the enum. Parses it as ContentControl
and passes back its content. Unfortunately during this step it loses the enum type information and subsequent type casting is not valid.
If you are working with sources and not just NuGet package you can fix it yourself. Just add another overload of Convert
method to TypeConverterHelper
:
public static Object Convert(string value, Type destinationType)
{
var typeInfo = destinationType.GetTypeInfo();
if (typeInfo.IsEnum)
return Enum.Parse(destinationType, value);
return Convert(value, destinationType.FullName);
}
And of course change the call in DataTriggerBehavior Compare method from:
rightOperand = TypeConverterHelper.Convert(rightOperand.ToString(), leftOperand.GetType().FullName);
to:
rightOperand = TypeConverterHelper.Convert(rightOperand.ToString(), leftOperand.GetType());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With