DataTriggerBehavior不能与Enum一起使用?

时间:2014-05-19 00:48:34

标签: xaml enums windows-runtime windows-store-apps

我尝试使用行为SDK中的DataTriggerBehavior。但它似乎与枚举无关......或者我做错了。

您可以假设这些示例的DataContext是这样的(INotifyPropertyChanged已实现,但我不会在此处显示):

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" };

以下代码不起作用(尝试指定枚举值并检查ItemCommand枚举属性):

<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>

并且此代码(检查枚举资源)也不起作用:

<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>

而这段代码(检查字符串)确实有效:

<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>

DataTriggerBehavior Value属性中指定枚举值的正确方法是什么,这样才能生效?

2 个答案:

答案 0 :(得分:1)

你可以写一个转换器:

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

在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>

或直接绑定到示例中的字符串。不幸的是,WinRT中的DataTriggerBehavior比Windows Phone 8中的DataTrigger更糟糕

答案 1 :(得分:0)

我正在调查此问题,并将问题缩小到TypeConverterHelper级。 TypeConverterHelper source

显然它没有考虑枚举类型,而是回退到重新创建枚举的xaml字符串的逻辑。将其解析为ContentControl并传回其内容。不幸的是,在此步骤中,它丢失了枚举类型信息,后续类型转换无效。

如果您正在使用源而不仅仅是NuGet包,您可以自己修复它。只需将Convert方法的另一个重叠添加到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);
}

当然,在DataTriggerBehavior比较方法中更改调用 从:

rightOperand = TypeConverterHelper.Convert(rightOperand.ToString(), leftOperand.GetType().FullName);

为:

rightOperand = TypeConverterHelper.Convert(rightOperand.ToString(), leftOperand.GetType());