DataStateBehavior для Enum вместо bool?Строка? - PullRequest
6 голосов
/ 15 июня 2010

Есть ли в WPF простой способ привязать VisualStates к значениям перечисления? Вроде как DataStateBehavior, но для Enum?

Ответы [ 4 ]

4 голосов
/ 26 февраля 2011

Лучший способ - просто пойти дальше и реализовать поведение, которое делает именно это -

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>
3 голосов
/ 09 февраля 2012

Вы можете сделать это в чистом xaml, используя DataTrigger для каждого возможного значения перечисления с каждым триггером, вызывающим GoToStateAction с различным состоянием. Смотрите пример ниже. Для более подробной информации взгляните на Перечисление, управляющее изменением визуального состояния через 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>
1 голос
/ 25 марта 2011

В SL существует DataStateSwitchBehavior, который можно перенести в WPF: У кого-нибудь есть DataStateSwitchBehavior для WPF4?

синтаксис довольно прост:

 <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/>
0 голосов
/ 03 декабря 2016

У меня возникли проблемы с приведенным выше ответом EnumStateBehavior.

Обработчик PropertyChanged сначала сработает, когда AssociatedObject имеет значение null (поскольку привязка установлена, но поведение еще не присоединено).Кроме того, даже когда поведение впервые присоединено, целевые элементы анимации 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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...