Запуск анимации из события с использованием MVVM

Кажется, я здесь достиг своего рода критической точки MVVM.

Я хотел бы, чтобы непрозрачность элемента управления анимировалась на полсекунды (DoubleAnimation от 0,5 до 1,0), когда у базового объекта модели представления изменилось свойство «Статус». Сначала я добился этого с помощью DataTrigger, но поскольку я не нашел способа реагировать на ЛЮБЫЕ изменения, только на заданное значение, мне приходилось всегда переводить свойство «Статус» объектов виртуальной машины на специальное «ожидающее» значение перед его установкой. до предполагаемой стоимости. (Кстати, есть ли способ отреагировать на ЛЮБЫЕ изменения?)

Это было взломано, поэтому вместо этого я начал возиться с EventTriggers ...

Это то, что я пробовал до сих пор:

  1. Использование обычного EventTrigger

Кажется, для этого требуется RoutedEvent, но это, в свою очередь, требует, чтобы мой базовый объект модели представления унаследовал от DependencyObject.

  1. Использование i: Interaction.Triggers

Таким образом я могу слушать и реагировать на обычные события .NET, но я не нашел способа запустить StoryBoard с использованием этого подхода.

  1. Использование i: Interaction.Triggers и запись Behavior

Этот эксперимент не оправдал ожиданий из-за того, что я не нашел способа привязать свое собственное поведение к соответствующему элементу управления.

Вот как выглядел XAML:

   <cc:MyControl>
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Updated">
                <i:Interaction.Behaviors>
                    <cv:OpacityBehavior Duration="0:0:0:5" />
                </i:Interaction.Behaviors>
            </i:EventTrigger>
        </i:Interaction.Triggers>

А вот настраиваемое поведение:

class OpacityBehavior : Behavior<MyControl>
{
    public Duration Duration { get; set; }

    protected override void OnAttached()
    {
        base.OnAttached();
        var animation = new DoubleAnimation(0.5, 1, Duration, FillBehavior.HoldEnd);
        var associatedObject = lookupVisualParent(this);
        associatedObject.BeginAnimation(UIElement.OpacityProperty, animation);
    }
}

Это не сработало, потому что синтаксический анализатор XAML требовал, чтобы он был прикреплен непосредственно к MyControl, но мне нужно прикрепить его к триггер события. Затем я попробовал такой подход:

class OpacityBehavior : Behavior<DependencyObject>
{
    public Duration Duration { get; set; }

    protected override void OnAttached()
    {
        base.OnAttached();
        var animation = new DoubleAnimation(0.5, 1, Duration, FillBehavior.HoldEnd);
        var associatedObject = lookupVisualParent(this);
        associatedObject.BeginAnimation(UIElement.OpacityProperty, animation);
    }

    private UIElement lookupVisualParent(DependencyObject dObj)
    {
        if (dObj is UIElement)
            return (UIElement) dObj;

        if (dObj == null)
            return null;

        return lookupVisualParent(LogicalTreeHelper.GetParent(dObj));
    }
}

Это не удалось из-за того, что lookupVisualParent не работает. Логический родитель поведения всегда null .

Мне кажется, это должна быть довольно распространенная задача? Есть ли хорошее решение этой проблемы? Мне кажется странным, что мне придется писать классы моей модели представления так, чтобы они были производными от DependencyObject , чтобы запускать анимацию при возникновении события.

Ура

7
задан Jonas Rembratt 19 October 2011 в 16:59
поделиться