DataTriggerBehavior Doesn't Work With Enum?

点点圈 提交于 2020-01-03 16:01:12

问题


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?


回答1:


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




回答2:


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());


来源:https://stackoverflow.com/questions/23728327/datatriggerbehavior-doesnt-work-with-enum

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!