如果在完成动画之前发生多个触发器,如何增加动画的持续时间?

时间:2014-06-25 10:05:21

标签: c# wpf animation wpf-animation coloranimation

我有一个简单的彩色动画:

<TextBlock Foreground="{DynamicResource xxx}" Text="{Binding DataContext.Value, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type xcdg:DataCell}}}" >
    <TextBlock.Style>
        <Style TargetType="TextBlock" >
            <Style.Triggers>
                <DataTrigger Binding="{Binding DataContext.ValueChanged, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type xcdg:DataCell}}}" Value="True">
                     <DataTrigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard >
                                <ColorAnimation AutoReverse="True" From="{StaticResource NormalForeground}" To="{StaticResource ModifiedForeground}" Duration="0:0:1" Storyboard.TargetProperty="Foreground.Color" FillBehavior="Stop" />
                            </Storyboard>
                        </BeginStoryboard>
                     </DataTrigger.EnterActions>
                 </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

正如您所看到的,当DataContext.ValueChanged为true时会发生这种情况。这是一个真实的布尔值 - &gt;每次需要时都是假的。通常,动画需要1秒才能执行,如果在动画已经运行时发生多个DataContext.ValueChanged,我想要的是延长时间。

所以,如果我这样做:

                   DataContext.ValueChanged: start animation for 1 second.
After 0.5 seconds: DataContext.ValueChanged: the animation will last 1.5 second.
After 1.0 seconds: DataContext.ValueChanged: the animation will last 1.5 second more.

基本上每次DataContext.ValueChanged值变为true时,第二个都会添加到ColorAnimation中,它必须保持To:颜色,直到它必须开始面朝外。

谢谢!

修改

我在viewmodel代码中有这样的代码:

(...)
if (condition)
{
    this.ValueChanged = true;
    this.ValueChanged = false;
}
(...)

此代码每秒调用一次,动画持续时间也设置为一秒所以如果条件满足,则预期输出是TextBox保留To颜色直到条件为false然后执行渐变到From颜色。

希望现在更清楚了!

编辑2:

这是一个演示此问题的项目。执行它并在TextBox上键入,如果每个键键入的速度超过一秒,则文本应保持红色。当你减少到每个键少于一秒时,动画应该完全执行:

Project source and binaries

编辑3:

在此处添加了项目的源代码:

XAML:

<Window x:Class="AnimationTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel Background="#444444">
        <TextBox Name="Box" Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Foreground="White" Background="#444444" >

        </TextBox>
        <TextBlock Text="{Binding Text}"  Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="24" >
            <TextBlock.Style>
                <Style TargetType="TextBlock" >
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ValueChanged}" Value="True">
                                <DataTrigger.EnterActions>
                                <BeginStoryboard>
                                    <Storyboard >
                                        <ColorAnimation AutoReverse="True" From="White" To="Red" Duration="0:0:1" Storyboard.TargetProperty="Foreground.Color" FillBehavior="Stop" RepeatBehavior="Forever" />
                                    </Storyboard>
                                </BeginStoryboard>
                                </DataTrigger.EnterActions>
                            </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
        </TextBlock>
    </StackPanel>
</Window>

CODE:

using System.ComponentModel;
using System.Windows;

namespace AnimationTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window , INotifyPropertyChanged
    {
        private string _text;
        private bool _valueChanged;

        public string Text
        {
            get { return _text; }
            set
            {
                _text = value;
                this.OnPropertyChanged("Text");
                this.ValueChanged = true;
                this.ValueChanged = false;
            }
        }

        public bool ValueChanged
        {
            get
            {
                return _valueChanged;
            }
            set
            {
                _valueChanged = value;
                this.OnPropertyChanged("ValueChanged");
            }
        }

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

0 个答案:

没有答案