动画,Image.Source和绑定

时间:2013-07-26 17:27:43

标签: c# wpf

我有这个视图模型:

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时为视图中的图像设置动画(从FlashIsFlashing == 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>

1 个答案:

答案 0 :(得分:2)

最简单的解决方案可能是有两个重叠的图像 - 一个绑定到Normal源,一个绑定到Flash源。然后,您可以使用Storyboard为两张图片上的Visibility属性设置动画。