动画、图像、源和绑定
本文关键字:绑定 图像 动画 | 更新日期: 2023-09-27 18:25:01
我有这个视图模型:
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;
}
当IsFlashing == true
时,我想为视图中的图像设置动画(从Normal
到Flash
再返回)。为了证明我正在努力实现的目标,我将发布一段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>
最简单的解决方案可能是有两个重叠的图像——一个绑定到Normal
源,另一个绑定至Flash
源。然后,可以使用Storyboard
为两个图像上的Visibility
属性设置动画。