Почему, когда одна и та же анимация запускается до завершения предыдущей, затухание не работает?

#c# #wpf #fade #wpf-animation #coloranimation

#c# #wpf #затухание #wpf-анимация #coloranimation

Вопрос:

У меня есть следующая простая анимация:

 <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="Black">
        <TextBox Name="Box" >

        </TextBox>
        <TextBlock Text="{Binding Text, ElementName=Box, NotifyOnTargetUpdated=True}"  Foreground="White" >
            <TextBlock.Style>
                <Style TargetType="TextBlock"  >
                    <Style.Triggers>
                        <EventTrigger RoutedEvent="Binding.TargetUpdated">
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimation AutoReverse="True" To="#A933FF" Duration="0:0:1" Storyboard.TargetProperty="Foreground.Color" FillBehavior="Stop" IsCumulative="True" />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
        </TextBlock>
    </StackPanel>
</Window>
  

Это просто делает flash значением при изменении значения. если вы пишете букву, вы видите, что она правильно мигает в соответствии с цветом, установленным в анимации, и возвращается назад. Но если вы нажмете несколько раз, продолжительность будет больше (что является желаемым поведением), но затем она переходит к исходному цвету без затухания. Почему это происходит и как этого избежать?

Ответ №1:

Итак, еще раз, у нас возникает вопрос, когда пользователь предоставляет некоторый код и говорит, почему это происходит?Ответ в этом случае является обычным ответом на эти вопросы:

Вы написали некоторый код, чтобы это произошло

Итак, чтобы копнуть немного глубже, вы спросили:

если вы пишете букву, вы видите, что она правильно мигает в соответствии с цветом, установленным в анимации, и возвращается назад. Но если вы нажмете несколько раз, продолжительность будет больше (что является желаемым поведением), но затем она переходит к исходному цвету без затухания. Почему это происходит и как этого избежать?

Во-первых, почему это происходит?

Итак, причина, по которой это происходит, заключается в том, что вы объявили a ColorAnimation , для которого не From установлено значение, поэтому оно всегда будет начинаться с текущего значения, независимо от того, было ли это значение обработано an Animation или нет:

 <ColorAnimation AutoReverse="True" To="#A933FF" Duration="0:0:1" FillBehavior="Stop" 
    Storyboard.TargetProperty="Foreground.Color" IsCumulative="True" />
  

Для одного введенного символа вы увидите ColorAnimation , как и ожидали. Однако, когда вы постоянно вводите дополнительные символы, он уже достиг заданного вами фиолетового цвета, и вы не увидите никаких дальнейших анимаций, пока не прекратите печатать, потому что теперь он пытается анимировать ваш фиолетовый цвет до того же фиолетового цвета.

Теперь, как этого избежать?

Чтобы устранить эту проблему, либо укажите From цвет, либо установите Duration его намного быстрее, или, предпочтительно, оба:

 <ColorAnimation AutoReverse="True" From="White" To="#A933FF" Duration="0:0:0.1" 
    Storyboard.TargetProperty="Foreground.Color" FillBehavior="Stop" 
    IsCumulative="True" />
  

Комментарии:

1. Итак, еще раз, у нас есть ответ, в котором опытный пользователь дает хороший ответ, поэтому мой ответ — обычный ответ на эти ответы: спасибо!!!. В любом случае я удалил From через некоторое время, потому что я действительно не знаю, какой цвет он будет иметь в начале, поскольку он поступает из динамического ресурса, а затем вы сталкиваетесь с проблемой настройки ресурсов для анимации и замораживаемых файлов … : S.

Ответ №2:

Вы можете достичь желаемого результата, используя ColorAnimationUsingKeyFrames это, это даст вам гораздо более точный контроль над тем же, используя ключевые кадры, вместо того, чтобы отменять двойную анимацию, которая теряет начальное значение после многократного вызова, и FillBehavior stop принудительно возвращает его к исходному значению в результате завершения анимации

пример для вас

 <TextBlock Text="{Binding Text, ElementName=Box, NotifyOnTargetUpdated=True}"  Foreground="White" >
    <TextBlock.Style>
        <Style TargetType="TextBlock">
            <Style.Triggers>
                <EventTrigger RoutedEvent="Binding.TargetUpdated">
                    <BeginStoryboard>
                        <Storyboard>
                            <ColorAnimationUsingKeyFrames Duration="0:0:2" Storyboard.TargetProperty="Foreground.Color" >
                                <SplineColorKeyFrame Value="#A933FF"/>
                                <SplineColorKeyFrame Value="White" KeyTime="0:0:1"/>
                            </ColorAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>
  

более чистый подход предполагает остановку предыдущей раскадровки и вызов новой

 <TextBlock Text="{Binding Text, ElementName=Box, NotifyOnTargetUpdated=True}"  Foreground="White" >
    <TextBlock.Style>
        <Style TargetType="TextBlock"  >
            <Style.Resources>
                <Storyboard x:Key="animate">
                    <ColorAnimationUsingKeyFrames Duration="0:0:2" Storyboard.TargetProperty="Background.Color" >
                        <SplineColorKeyFrame Value="#A933FF"/>
                        <SplineColorKeyFrame Value="White" KeyTime="0:0:1"/>
                    </ColorAnimationUsingKeyFrames>
                </Storyboard>
            </Style.Resources>
            <Style.Triggers>
                <EventTrigger RoutedEvent="Binding.TargetUpdated">
                    <StopStoryboard BeginStoryboardName="beginAnimate"/>
                    <BeginStoryboard x:Name="beginAnimate" Storyboard="{StaticResource animate}"/>
                </EventTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>