Стартирайте Storyboard в друга времева линия на Storyboards

Имам сценарий (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

Благодаря, Мегакемп, точно това се страхувах да направя. Не исках да трябва да управлявам две копия на разкадровка в 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
Не е нужно да управлявате две копия, просто използвайте make the storyboard a resource и се обърнете към него два пъти! - person Bob King; 15.10.2008
comment
Забавянето на старта е зададено на самия обект Storyboard, така че той ще трябва да има две копия, едно със закъснението и едно без. - 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 и вместо това накрая използвате use imperative code. - person Enrico Campidoglio; 20.10.2008