tags:

views:

1188

answers:

3

Hi there.

I have a storyboard(1) that does some basic animations in 2 seconds. I want the storyboard(1) to do all the property animations I have set it up to do (this all works fine). But at 3 seconds into the storyboard(1) I want to begin storyboard(2) and exit storyboard(1) without user interaction at all.

Only thing I've seen that allows me to do this is when the user clicks on something. I want this to be automatic based on the position of the current storyboard(1) timeline.

I hope this makes enough sense. Please let me know if you need me to explain something in more detail.

Thanks.

Edit: Please post the answer in XAML or VB.net language. :)

+4  A: 

Normally in order to control animations during the timeline you would use "keyframes". Keyframe animations allow you to define specific values for the property you are animating at specific times. In WPF every animation has a corresponding keyframe animation, like 'DoubleAnimation' has 'DoubleAnimationUsingKeyFrames'.

I don't think it's possible to start a new storyboard from within an animation. However you could achieve the same result by having both storyboards on the same timeline and starting storyboard(2) with a specific delay based on the duration of storyboard(1). Something like:

<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>

Here the color animation will start 1 second after the width animation has finished. It could be worth a try.

Enrico Campidoglio
A: 

Thanks Megakemp, that's what I was afraid of having to do. I didn't want to have to manage two copies of a storyboard in XAML. If I have to add a control and manage it via storyboard(1) I will have to remember to copy and paste the changes to this other storyboard(2). I guess those are the hoops you have to jump thru until the functionality comes that I'm looking for.

Now I did think of another idea to try but wasn't able to get the functionality. This is my idea below, I can explain it better in code.. this below code will not compile, its just to get my point across.

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

Thanks for your help.. and if anyone else has another answer or more insight please don't hesitate to post, I'm not abandoning this idea completely yet.

ScottN
You don't have to manage two copies, just use make the storyboard a resource and refer to it twice!
Bob King
The start delay is set on the Storyboard object itself, so he will need to have two copies, one with the delay and one without.
Enrico Campidoglio
Bob King, please provide an example of your solution so I can better understand what your speaking of.Megakemp, your on the same page as my thinking.
ScottN
A: 

Well I came up with a solution. I just spawned a new thread to wait for 3 seconds and then did an Invoke call to run the storyboard from that thread.

    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

Do your thread safe delegates and functions and you'll have it working. It's a ugly hack in my opinion, but it works for now.

ScottN
Yeah, it's always a pity when you can't solve a UI problem 100% in XAML, and instead end up using use imperative code.
Enrico Campidoglio