我正在尝试制作一个WPF(4.6.2)数据模板,该模板将在特定ViewModel属性设置为true时执行动画,然后在动画完成后将属性设置为false(不仅是在它开始了。)
这是一次尝试:
<DataTemplate DataType="...">
<Border x:Name="Bd" ...>
<Border.Resources>
<Storyboard x:Key="Animate" FillBehavior="Stop">
<DoubleAnimation Storyboard.TargetName="Bd"
Storyboard.TargetProperty="Opacity"
From="0" To="1" Duration="0:0:3" />
</Storyboard>
</Border.Resources>
...
<i:Interaction.Triggers>
<ei:DataTrigger Binding="{Binding ShouldAnimate}" Value="true">
<ei:ControlStoryboardAction Storyboard="{StaticResource Animate}"
ControlStoryboardOption="Play" />
</ei:DataTrigger>
<ei:StoryboardCompletedTrigger Storyboard="{StaticResource Animate}">
<ei:ChangePropertyAction TargetObject="{Binding}"
PropertyName="ShouldAnimate"
Value="false" />
</ei:StoryboardCompletedTrigger>
</i:Interaction.Triggers>
</Border>
</DataTemplate>
如果我仅在属性已经创建UI后后将其设置为true,此方法就可以了。...
如果该属性为true,则什么都不会发生(情节提要板未启动,并且该属性未重置)。(对于将Storyboard声明为本地资源以使TargetName可以正常工作,我也不太满意,但这似乎是必需的。)
另一种尝试是使用普通的DataTrigger:
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding ShouldAnimate}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Animate}" />
</DataTrigger.EnterActions>
</DataTrigger>
</DataTemplate.Triggers>
即使属性是预先设置的,也可以成功制作动画(尽管奇怪的是,必须未指定{>),Storyboard.TargetName
不能被指定,并且情节提要板本身必须完全声明为DataTemplate
,或嵌入BeginStoryboard
内而不使用资源)。但是我无法找到在动画完成后重置属性的任何好方法。
Storyboard.Completed
乍一看似乎很有希望,但是它似乎不包含有关调用哪个实例以及因此需要更新哪个ViewModel的任何上下文信息。 (看来StoryboardCompletedTrigger
在内部使用了此功能,但依赖于拥有本地情节提要实例,而不是全局资源。我尚未使用多个模板实例对此进行测试,但是重要的是,完成一个情节提要不会影响另一个。)
我尝试将两者结合在一起(在Vanilla DataTrigger中启动情节提要,并在Interaction触发器中等待完成),但这导致StoryboardCompletedTrigger.Storyboard
引发解析错误“ Storyboard必须将IsFrozen设置为false才能进行修改”尝试附加到Completed事件处理程序时;大概是因为香草触发器被用作样式。