Кажется, я здесь достиг своего рода критической точки MVVM.
Я хотел бы, чтобы непрозрачность элемента управления анимировалась на полсекунды (DoubleAnimation от 0,5 до 1,0), когда у базового объекта модели представления изменилось свойство «Статус». Сначала я добился этого с помощью DataTrigger, но поскольку я не нашел способа реагировать на ЛЮБЫЕ изменения, только на заданное значение, мне приходилось всегда переводить свойство «Статус» объектов виртуальной машины на специальное «ожидающее» значение перед его установкой. до предполагаемой стоимости. (Кстати, есть ли способ отреагировать на ЛЮБЫЕ изменения?)
Это было взломано, поэтому вместо этого я начал возиться с EventTriggers ...
Это то, что я пробовал до сих пор:
EventTrigger
Кажется, для этого требуется RoutedEvent, но это, в свою очередь, требует, чтобы мой базовый объект модели представления унаследовал от DependencyObject.
i: Interaction.Triggers
Таким образом я могу слушать и реагировать на обычные события .NET, но я не нашел способа запустить StoryBoard
с использованием этого подхода.
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
, чтобы запускать анимацию при возникновении события.
Ура