6

WPF 中是否有一种简单的方法可以将 VisualStates 绑定到枚举值?有点像 DataStateBehavior,但对于枚举?

4

4 回答 4

4

最好的方法是继续执行一个 Behavior 来做到这一点 -

public class EnumStateBehavior : Behavior<FrameworkElement>
{
    public object EnumProperty
    {
        get { return (object)GetValue(EnumPropertyProperty); }
        set { SetValue(EnumPropertyProperty, value); }
    }

    // Using a DependencyProperty as the backing store for EnumProperty.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty EnumPropertyProperty =
        DependencyProperty.Register("EnumProperty", typeof(object), typeof(EnumStateBehavior), new UIPropertyMetadata(null, EnumPropertyChanged));

    static void EnumPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        if (e.NewValue == null) return;

        EnumStateBehavior eb = sender as EnumStateBehavior;

        VisualStateManager.GoToElementState(eb.AssociatedObject, e.NewValue.ToString(), true);
    }

}

用法非常简单——使用如下:

<i:Interaction.Behaviors>
        <local:EnumStateBehavior EnumProperty="{Binding MyEnumProperty}" />
</i:Interaction.Behaviors>
于 2011-02-26T00:22:42.377 回答
3

您可以在纯 xaml 中执行此操作,方法是使用每个可能的枚举值的 DataTrigger,每个触发器调用具有不同状态的 GoToStateAction。请参见下面的示例。有关更多详细信息,请查看 Enum 通过 ViewModel 驱动视觉状态更改

    <i:Interaction.Triggers>
        <ei:DataTrigger Binding="{Binding ConfirmedAnswerStatus}" Value="Unanswered">
            <ei:GoToStateAction StateName="UnansweredState" UseTransitions="False" />
        </ei:DataTrigger>
        <ei:DataTrigger Binding="{Binding ConfirmedAnswerStatus}" Value="Correct">
            <ei:GoToStateAction StateName="CorrectlyAnsweredState" UseTransitions="True" />
        </ei:DataTrigger>
        <ei:DataTrigger Binding="{Binding ConfirmedAnswerStatus}" Value="Incorrect">
            <ei:GoToStateAction StateName="IncorrectlyAnsweredState" UseTransitions="True" />
        </ei:DataTrigger>
    </i:Interaction.Triggers>
于 2012-02-09T18:46:35.120 回答
1

SL 中有一个 DataStateSwitchBehavior 可以移植到 WPF:有人有 WPF4 的 DataStateSwitchBehavior 吗?

语法非常简单:

 <is:DataStateSwitchBehavior Binding="{Binding Orientation}">
     <is:DataStateSwitchCase Value="Left" State="LeftState"/>
     <is:DataStateSwitchCase Value="Right" State="RightState"/>
     <is:DataStateSwitchCase Value="Down" State="DownState"/>
     <is:DataStateSwitchCase Value="Up" State="UpState"/>
 <is:DataStateSwitchCase/>
于 2011-03-25T16:49:02.957 回答
0

我对上述 EnumStateBehavior 答案有疑问。

当 AssociatedObject 为 null 时,PropertyChanged 处理程序将首先触发(因为已设置绑定但尚未附加 Behavior)。此外,即使第一次附加行为,VisualState 动画的目标元素可能还不存在,因为该行为可能已在其他子视觉树之前附加。

解决方案是在关联对象上使用 Loaded 事件来确保设置绑定的初始状态。

public class EnumStateBehavior : Behavior<FrameworkElement>
{
    public static readonly DependencyProperty BindingProperty =
        DependencyProperty.Register(nameof(Binding), typeof(object), typeof(EnumStateBehavior), new UIPropertyMetadata(null, BindingPropertyChanged));

    public object Binding
    {
        get { return (object)GetValue(BindingProperty); }
        set { SetValue(BindingProperty, value); }
    }

    protected override void OnAttached()
    {
        base.OnAttached();

        this.AssociatedObject.Loaded += AssociatedObject_Loaded;
    }

    protected override void OnDetaching()
    {
        this.AssociatedObject.Loaded -= AssociatedObject_Loaded;
        base.OnDetaching();
    }

    private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
    {
        if (Binding != null)
            GoToState();
    }

    private void GoToState()
    {
        VisualStateManager.GoToElementState(this.AssociatedObject, Binding.ToString(), true);
    }

    private static void BindingPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var eb = (EnumStateBehavior)sender;

        if (e.NewValue == null || eb.AssociatedObject == null || !eb.AssociatedObject.IsLoaded)
            return;

        eb.GoToState();
    }
}
于 2016-12-02T22:58:39.330 回答