我似乎已经达到了某种MVVM的突破点。
当底层视图模型对象的“Status”属性发生变化时,我希望控件的不透明度动画半秒(DoubleAnimation从0.5到1.0)。我最初使用DataTrigger实现了这一点,但由于我没有找到对任何更改作出反应的方法,只是一个给定的值,我必须始终在设置它之前将VM对象“Status”属性翻转为特殊的“pending”值达到预期的价值。 (有没有办法对任何改变做出反应?)
这很hacky所以我开始摆弄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
,以便在事件触发时启动动画。
干杯
答案 0 :(得分:4)
你可以简单地使用一个标志:在你的VM上设置一个名为'RecentChangedFlag'的标志。每当适当的值发生变化时,将其脉冲为true
,然后false
。你可以这样做:
private bool _changedFlag;
public bool ChangedFlag
{
get
{
if (_changedFlag)
{
_changedFlag = false;
OnPropertyChanged("ChangedFlag");
return true;
}
// (else...)
return false;
}
protected set
{
_changedFlag = value;
OnPropertyChanged("ChangedFlag");
}
}
即,当您想要通知动画开始时,使用上面的代码集ChangedFlag = true
。在WPF查询真值后,它将被重置为false。
然后,当RecentlyChangedFlag
的值为true
时,动画就会出现,例如EnterAction
。
希望有所帮助。