我有这个视图模型:
public class ViewModel : ViewModelBase
{
public ViewModel()
{
// indeed, images are dynamically generated
normal = new BitmapImage(new Uri("Normal.jpg", UriKind.Relative));
flash = new BitmapImage(new Uri("Flash.jpg", UriKind.Relative));
}
public bool IsFlashing
{
get { return isFlashing; }
set
{
if (isFlashing != value)
{
isFlashing = value;
OnPropertyChanged("IsFlashing");
}
}
}
private bool isFlashing;
public ImageSource Normal
{
get { return normal; }
private set
{
if (normal != value)
{
normal = value;
OnPropertyChanged("Normal");
}
}
}
private ImageSource normal;
public ImageSource Flash
{
get { return flash; }
set
{
if (flash != value)
{
flash = value;
OnPropertyChanged("Flash");
}
}
}
private ImageSource flash;
}
我希望在Normal
时为视图中的图像设置动画(从Flash
到IsFlashing == true
然后再返回)。
为了演示,我想要实现的目标,我将发布一段XAML:
<DataTemplate x:Key="MyTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<CheckBox Content="Is flashing" IsChecked="{Binding IsFlashing}"/>
<Image x:Name="MyImage" Grid.Row="1" Source="{Binding Normal}"/>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsFlashing}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MyImage"
Storyboard.TargetProperty="Source"
RepeatBehavior="Forever">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{Binding Normal}"/>
<DiscreteObjectKeyFrame KeyTime="0:0:1" Value="{Binding Flash}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
这不起作用,因为动画引擎无法使用绑定冻结故事板。 还有其他方法可以达到这个目的吗?
我可以在视图模型中使用计时器来解决这个问题......但这种方法很有气味。
更新 根据Richard Deeming的回答,数据模板看起来就是这样。它的工作原理肯定比计时器更好:
<DataTemplate x:Key="MyTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<CheckBox Content="Is flashing" IsChecked="{Binding IsFlashing}"/>
<Image x:Name="NormalImage" Grid.Row="1" Source="{Binding Normal}"/>
<Image x:Name="FlashImage" Grid.Row="1" Source="{Binding Flash}" Visibility="Collapsed"/>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsFlashing}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalImage"
Storyboard.TargetProperty="Visibility"
RepeatBehavior="Forever"
Duration="0:0:1">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
<DiscreteObjectKeyFrame KeyTime="0:0:0.5" Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FlashImage"
Storyboard.TargetProperty="Visibility"
RepeatBehavior="Forever"
Duration="0:0:1">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}"/>
<DiscreteObjectKeyFrame KeyTime="0:0:0.5" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard FillBehavior="Stop">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalImage"
Storyboard.TargetProperty="Visibility"
Duration="0:0:1">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard FillBehavior="Stop">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FlashImage"
Storyboard.TargetProperty="Visibility"
Duration="0:0:1">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
答案 0 :(得分:2)
最简单的解决方案可能是有两个重叠的图像 - 一个绑定到Normal
源,一个绑定到Flash
源。然后,您可以使用Storyboard
为两张图片上的Visibility
属性设置动画。