как вызвать обработчик события, когда анимация WPF повторяется - PullRequest
0 голосов
/ 19 апреля 2010

У меня есть анимация WPF с RepeatBehavior, установленной на Forever. Необходимо что-то обновлять каждый раз, когда анимация повторяется. Я не могу понять, как перехватить событие повтора, обработчик события Complete для этого не работает. Интервал анимации программируется и определяется некоторыми факторами окружающей среды. Так что использование таймера не является аккуратным подходом. Как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 24 января 2011

Я нашел довольно элегантное решение этой проблемы. Требуется только добавить EventHandler к событию CurrentTimeInvalidated элемента Timeline:

private TimeSpan _lastTime;

private void Animation_CurrentTimeInvalidated(object sender, EventArgs e)
{
    var clock = sender as AnimationClock;

    if (clock != null && clock.CurrentTime.HasValue)
    {
        if (clock.CurrentTime.Value < this._lastTime)
        {
            //TODO: Add any behavior to perform on a repeat here.
        }

        this._lastTime = clock.CurrentTime.Value;
    }
}
0 голосов
/ 19 апреля 2010

Вместо того чтобы иметь RepeatBehavior of Forever, просто запустите его один раз и поймайте событие Completed. Выполните обработку, а затем вызовите BeginAnimation, используя надлежащие свойства DependencyProperty и анимацию.

Например, вот (заведомо глупый) пример, чтобы показать, что я имею в виду.

XAML:

<TextBlock x:Name="txtExample" 
           Text="Gradients Are Neat"
           FontSize="50">
    <TextBlock.Foreground>
        <LinearGradientBrush x:Name="rgbForeground">
            <LinearGradientBrush.GradientStops>

                <GradientStop x:Name="Color1" Color="#12BC23" Offset="0.0" />
                <GradientStop x:Name="Color2" Color="#AA0499" Offset="0.5" />
                <GradientStop x:Name="Color3" Color="#792BDF" Offset="1.0" />
            </LinearGradientBrush.GradientStops>
        </LinearGradientBrush>
    </TextBlock.Foreground>
    <TextBlock.Triggers>
        <EventTrigger RoutedEvent="TextBlock.Loaded">
            <EventTrigger.Actions>
                <BeginStoryboard>
                    <Storyboard x:Name="SomeStoryboard">
                        <ColorAnimation x:Name="changeColor1"
                                        Storyboard.TargetName="Color1"
                                        Storyboard.TargetProperty="Color"
                                        Duration="0:0:3"
                                        To="#81AD21"/>
                        <ColorAnimation x:Name="changeColor2"
                                        Storyboard.TargetName="Color2"
                                        Storyboard.TargetProperty="Color"
                                        Duration="0:0:2"
                                        To="#29910A"/>
                        <ColorAnimation x:Name="changeColor3"
                                        Storyboard.TargetName="Color3"
                                        Storyboard.TargetProperty="Color"
                                        Duration="0:0:5"
                                        To="#BB4923" 
                                        Completed="changeColor3JustOnce_Completed" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger.Actions>
        </EventTrigger>
    </TextBlock.Triggers>
</TextBlock>

Код сзади:

private void changeColor3_Completed(object sender, EventArgs e)
{
    Color3.BeginAnimation(GradientStop.ColorProperty, changeColor3);
}

Обратите внимание, что событие Completed находится на раскадровке, несмотря на то, что оно было объявлено в анимации. Если бы в некоторых других анимациях RepeatForever было установлено в значение true, событие никогда не было бы запущено.

...