Я, кажется, достиг какой-то критической точки MVVM здесь.
Я бы хотел, чтобы у элемента управления была анимация его непрозрачности на полсекунды (DoubleAnimation от 0,5 до 1,0), когда базовый объект модели представления изменил свое свойство Status. Я достиг этого вначале, используя 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
, чтобы запустить анимацию при возникновении события.
Приветствия