Начать раскадровку на другой временной шкале раскадровки

У меня есть раскадровка (1), которая делает некоторые базовые анимации за 2 секунды. Я хочу, чтобы раскадровка (1) выполняла все заданные мной анимации свойств (все работает нормально). Но через 3 секунды после начала раскадровки (1) я хочу начать раскадровку (2) и выйти из раскадровки (1) вообще без взаимодействия с пользователем.

Единственное, что я видел, что позволяет мне это делать, - это когда пользователь что-то нажимает. Я хочу, чтобы это происходило автоматически в зависимости от положения текущей временной шкалы раскадровки (1).

Надеюсь, в этом есть смысл. Пожалуйста, дайте мне знать, если вам нужно, чтобы я что-то объяснил более подробно.

Спасибо.

Изменить: отправьте ответ на языке XAML или VB.net. :)


person ScottN    schedule 14.10.2008    source источник


Ответы (3)


Обычно для управления анимацией на временной шкале используются «ключевые кадры». Анимация по ключевым кадрам позволяет вам определять определенные значения для свойства, которое вы анимируете в определенное время. В WPF каждая анимация имеет соответствующую анимацию по ключевым кадрам, например, «DoubleAnimation» имеет «DoubleAnimationUsingKeyFrames».

Я не думаю, что можно создать новую раскадровку из анимации. Однако вы можете достичь того же результата, разместив обе раскадровки на одной временной шкале и запустив раскадровку (2) с определенной задержкой, зависящей от продолжительности раскадровки (1). Что-то типа:

<StackPanel>
    <Rectangle Name="recProgressBar"
               Fill="Orange"
               Width="1"
               Height="25"
               Margin="20"
               HorizontalAlignment="Left" />
    <Button Content="Start Animation"
            Width="150"
            Height="25">
        <Button.Triggers>
            <EventTrigger RoutedEvent="Button.Click">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="recProgressBar"
                                         Storyboard.TargetProperty="Width"
                                         From="0"
                                         To="250"
                                         Duration="0:0:2" />
                        <Storyboard BeginTime="0:0:3">
                            <ColorAnimation Storyboard.TargetName="recProgressBar"
                                            Storyboard.TargetProperty="Fill.Color"
                                            To="DarkGreen"
                                            Duration="0:0:1" />
                        </Storyboard>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Button.Triggers>
    </Button>
</StackPanel>

Здесь цветная анимация начнется через 1 секунду после завершения анимации ширины. Возможно, стоит попробовать.

person Enrico Campidoglio    schedule 15.10.2008

Спасибо, Megakemp, я этого и боялся. Мне не хотелось управлять двумя копиями раскадровки в XAML. Если мне нужно добавить элемент управления и управлять им с помощью раскадровки (1), мне придется не забыть скопировать и вставить изменения в эту другую раскадровку (2). Я думаю, это те обручи, через которые нужно прыгать, пока не появится функциональность, которую я ищу.

Теперь я подумал о другой идее, чтобы попробовать, но не смог получить функциональность. Это моя идея ниже, я могу лучше объяснить ее в коде ... этот ниже код не будет компилироваться, это просто для того, чтобы донести свою точку зрения.

Dim board As Storyboard = New Storyboard
board = DirectCast(TryFindResource("Animation1"), Storyboard)
If board IsNot Nothing Then
    board.Begin(Me)
    While board.GetCurrentState(Me) = ClockState.Active
        'Wait until Animation1 ends
    End While
    'Start Animation2
    board = DirectCast(TryFindResource("Animation2"), Storyboard)
    If board IsNot Nothing Then
        board.Begin(Me)
    End If
End If

Спасибо за вашу помощь ... и если у кого-то еще есть другой ответ или больше идей, пожалуйста, не стесняйтесь публиковать, я еще не отказываюсь от этой идеи полностью.

person ScottN    schedule 15.10.2008
comment
Вам не нужно управлять двумя копиями, просто сделайте раскадровку ресурсом и дважды обратитесь к нему! - person Bob King; 15.10.2008
comment
Задержка запуска задается в самом объекте раскадровки, поэтому у него должно быть две копии, одна с задержкой, а другая без. - person Enrico Campidoglio; 15.10.2008
comment
Боб Кинг, представьте, пожалуйста, пример вашего решения, чтобы я мог лучше понять, о чем вы говорите. Megakemp, ты на той же странице, что и мои мысли. - person ScottN; 15.10.2008

Я нашел решение. Я просто создал новый поток для ожидания в течение 3 секунд, а затем выполнил вызов Invoke для запуска раскадровки из этого потока.

    Dim board As Storyboard = New Storyboard
    board = DirectCast(TryFindResource("DoSplit"), Storyboard)
    If board IsNot Nothing Then
        board.Begin(Me, True)

        Dim t As Thread
        t = New Thread(AddressOf Me.WaitToHidePanel)
        t.SetApartmentState(ApartmentState.STA)
        t.Start()

    End If

Сделайте свои потокобезопасные делегаты и функции, и у вас все будет работать. На мой взгляд, это уродливый хакер, но пока он работает.

person ScottN    schedule 15.10.2008
comment
Да, всегда жаль, когда вы не можете решить проблему пользовательского интерфейса на 100% в XAML и вместо этого используете императивный код. - person Enrico Campidoglio; 20.10.2008