【问题标题】:DataTriggerBehavior Doesn't Work With Enum?DataTriggerBehavior 不适用于枚举?
【发布时间】:2014-05-19 00:48:34
【问题描述】:

我正在尝试使用 Behaviors 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 属性中指定枚举值的正确方法是什么?

【问题讨论】:

  • 我认为它是因为Enum 不能为空,所以它将默认为“EnumValue1”,因此当您设置它时它不会更改,因为它已经是“EnumValue1”,尝试更改为“EnumValue2”进行测试" 或将Enum 属性设为可为空(如果可能)

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


【解决方案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 更糟糕

【讨论】:

  • 他们在想什么……采用了不起的技术 (XAML) 并处处削弱它。这就是我目前对 UWP 的看法。
【解决方案2】:

我正在调查这个问题并将问题缩小到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 Compare 方法中的调用 来自:

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

到:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-05
    • 2016-12-26
    • 1970-01-01
    • 2021-03-02
    相关资源
    最近更新 更多