locked
Insert delay before state in Blend... RRS feed

  • Question

  • Hi,

    I created a state and I would like to add a delay of 2 seconds before it starts.  I tried clicking the TimeLine and doing things in there but I always end up with my state all fucked up !

    Any hints on how to do it in BLEND not relying to go in the xaml if possible.

    Here's the state :

    <VisualStateGroup x:Name="LanguageChoice" ei:ExtendedVisualStateManager.UseFluidLayout="True">
        <VisualStateGroup.Transitions>
        	<VisualTransition GeneratedDuration="0:0:0.5">
        		<VisualTransition.GeneratedEasingFunction>
        			<ExponentialEase EasingMode="EaseInOut" Exponent="5"/>
        		</VisualTransition.GeneratedEasingFunction>
        	</VisualTransition>
        </VisualStateGroup.Transitions>
        <VisualState x:Name="Normal"/>
        <VisualState x:Name="ShowLanguageChoice">
        	<Storyboard>
        		<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="lstLanguage" d:IsOptimized="True"/>
        		<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="lstLanguage" d:IsOptimized="True"/>
        	</Storyboard>
        </VisualState>
    </VisualStateGroup>
    

    Thursday, August 16, 2012 10:26 PM

Answers

  • Here's the video you requested on how I went about it.  Sorry to take so long I the phone kept ringing, but it sounds like you have it worked out.

    http://sdrv.ms/S1MfNd

    But I think you should go with Chuck's trigger idea and use the animation you had originally created. 

    I've put away the Blend for SL5 because I also was getting constant crashes.  Sorry for your trouble.

    ~Christine


    My Gallery

    • Marked as answer by GearWorld Friday, August 17, 2012 5:00 PM
    Friday, August 17, 2012 4:10 PM
  • I don't believe it will work with a VisualState as the timing for the VisualStateManager seems to override it.

    If you put your animation in a Storyboard and don't use VisualStateManager, K.S.'s suggestion will work.

    You could also set your GoToStateAction on a TimerTrigger...

    		<i:Interaction.Triggers>
    			<ei:TimerTrigger MillisecondsPerTick="2000" TotalTicks="1">
    				<ei:GoToStateAction StateName="VisualState"/>
    			</ei:TimerTrigger>
    		</i:Interaction.Triggers>

     Anyways, it looks like the others have you covered.  Have a great weekend and I hope you get it all worked out quickly and easily.

    ~Christine


    My Gallery

    • Marked as answer by GearWorld Friday, August 17, 2012 4:59 PM
    Friday, August 17, 2012 4:58 PM

All replies

  • Hello Gear.

    Blend makes what you described very easy.  If you hit F6 to go to the Animation Workspace, you'll get a screen that looks similar to this...

    If the timeline is not showing click the "Show Timeline" button I circled in red.  Then you can create keyframes and set your animation up much like you would a regular storyboard.  You also don't have to be in Animation mode but it can make working with larger timelines a bit easier.

    In the above sample the rectangle goes from 0 to 100 opacity in the first 2 seconds and then shoots across the screen.

    		<VisualStateManager.VisualStateGroups>
    			<VisualStateGroup x:Name="VisualStateGroup">
    				<VisualStateGroup.Transitions>
    					<VisualTransition GeneratedDuration="0:0:2.5">
    						<VisualTransition.GeneratedEasingFunction>
    							<QuadraticEase EasingMode="EaseOut"/>
    						</VisualTransition.GeneratedEasingFunction>
    					</VisualTransition>
    				</VisualStateGroup.Transitions>
    				<VisualState x:Name="myState">
    					<Storyboard>
    						<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="rectangle">
    							<!--Move Box After 2 Seconds.  First line is the start value and second line is the end time with end value.-->
    							<EasingDoubleKeyFrame KeyTime="0:0:2" Value="0"/>
    							<EasingDoubleKeyFrame KeyTime="0:0:2.5" Value="540"/>
    						</DoubleAnimationUsingKeyFrames>
    						<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="rectangle">
    							<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
    							<EasingDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
    						</DoubleAnimationUsingKeyFrames>
    					</Storyboard>
    				</VisualState>
    			</VisualStateGroup>
    		</VisualStateManager.VisualStateGroups>

    Hope that helps.

    ~Christine


    My Gallery


    Friday, August 17, 2012 3:09 PM
  • Hi,

    Thank you for this hint.

    What you show me here is exactly where I go however it seems you add your keyframe before creating your state as for me my state already exist and in the timeline it's all at 0.  I'm unable to create a second keyframe at let say 2 seconds and move the time so it begins at 2 seconds

    I really don't know how to insert this 2 seconds by blend on an existing state prior to add any keyframe.
    Either I don't understand how you did this or what you show is doing it during the creation of the state.

    If it's not asking too much, a small video showing how to insert 2 seconds before the animation begins on an existing state that starts a 0

    • Edited by GearWorld Friday, August 17, 2012 3:16 PM
    Friday, August 17, 2012 3:15 PM
  • I believe you would need to change your DoubleAnimation to DoubleAnimationUsingKeyFrames and then add your KeyFrames for this to work.

    Similar to this based on your original code...

    	<Grid x:Name="LayoutRoot" Background="White">
    		<VisualStateManager.VisualStateGroups>
    			<VisualStateGroup x:Name="LanguageChoice">
    				<VisualStateGroup.Transitions>
    					<VisualTransition GeneratedDuration="0">
    						<VisualTransition.GeneratedEasingFunction>
    							<ExponentialEase EasingMode="EaseOut" Exponent="5"/>
    						</VisualTransition.GeneratedEasingFunction>
    					</VisualTransition>
    				</VisualStateGroup.Transitions>
    				<VisualState x:Name="ShowLanguageChoice">
    					<Storyboard>
    						<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="LanguageCombo">
    							<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
    							<EasingDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
    						</DoubleAnimationUsingKeyFrames>
    						<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="LanguageCombo">
    							<EasingDoubleKeyFrame KeyTime="0:0:2" Value="0"/>
    							<EasingDoubleKeyFrame KeyTime="0:0:2.5" Value="110"/>
    						</DoubleAnimationUsingKeyFrames>
    					</Storyboard>
    				</VisualState>
    			</VisualStateGroup>
    		</VisualStateManager.VisualStateGroups>
    		<i:Interaction.Triggers>
    			<i:EventTrigger>
    				<ei:GoToStateAction StateName="ShowLanguageChoice"/>
    			</i:EventTrigger>
    		</i:Interaction.Triggers>
    		<ComboBox x:Name="LanguageCombo" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Opacity="0" RenderTransformOrigin="0.5,0.5">
    			<ComboBox.RenderTransform>
    				<CompositeTransform/>
    			</ComboBox.RenderTransform>
    		</ComboBox>
    	</Grid>
    ~Christine

    My Gallery

    Friday, August 17, 2012 3:29 PM
  • Hi,

    Thank you for this hint.

    What you show me here is exactly where I go however it seems you add your keyframe before creating your state as for me my state already exist and in the timeline it's all at 0.  I'm unable to create a second keyframe at let say 2 seconds and move the time so it begins at 2 seconds

    I really don't know how to insert this 2 seconds by blend on an existing state prior to add any keyframe.
    Either I don't understand how you did this or what you show is doing it during the creation of the state.

    If it's not asking too much, a small video showing how to insert 2 seconds before the animation begins on an existing state that starts a 0

    Are you by chance working with one of the new Blend Preview versions?  The example I provided works in Blend 4 I have not tested it in another version.

    ~Christine


    My Gallery

    Friday, August 17, 2012 3:32 PM
  • Blend for Silverlight 5 Preview

    But I don't think this changed.  It's just that I'm unable to figure out how in Blend with the timeline on an existing state to have it start at 2 seconds but what I see there is that all points are at 0 with no keyframe.  If I try to add keyframe it does and I see I can move the time but it's nor working as if it looks that I'm breaking something originaly made not using keyframe but why Blend let you do this visually in the timeline if it doesn't make the real thing.  It bugs me because I can't figure out how to just add 2 seconds in front of that nimation that doesn't use keyframe.

    I think I'm going to try to redo my animation but first showing the timeline, adding a keyframe at 0 and then doing my animation.  Maybe then I will be able to move the time from 0 - 2 to 1 -2

    Friday, August 17, 2012 3:38 PM
  • Yeah right.  Blend just crashed.
    Trying again !

    Friday, August 17, 2012 3:39 PM
  • Now it seems to work.  Just one thing I see however is that
    Because I did it this way which is add a keyframe at 0 prior to start my animation,  Blend seems unable to play the animation fluidly even thought the 2 buttons for that are clicked :

    Friday, August 17, 2012 3:45 PM
  • How are you triggering the state? In theory you could add a delay before you trigger the state. If it is in code, you could put in a delay there, if it is using a behavior, I could show you how to make a trigger than has a delay built in.
    Friday, August 17, 2012 3:48 PM
    Moderator
  • Here's the video you requested on how I went about it.  Sorry to take so long I the phone kept ringing, but it sounds like you have it worked out.

    http://sdrv.ms/S1MfNd

    But I think you should go with Chuck's trigger idea and use the animation you had originally created. 

    I've put away the Blend for SL5 because I also was getting constant crashes.  Sorry for your trouble.

    ~Christine


    My Gallery

    • Marked as answer by GearWorld Friday, August 17, 2012 5:00 PM
    Friday, August 17, 2012 4:10 PM
  • Great video.

    Base on it I see you really do what I just did which I did not know the first time that is, adding a keyframe at 0 before starting the animation because if you try to add 2 seconds of delay when you don't do it this way well, you seem to be doomed.

    As for Chuck's idea of adding delay in code before calling the VisualStateManager.GoToState I tought about it.  I just wanted to make it entirely in Blend the easiest way.

    Well,  I like the Blend way showed in the video.  Thank you for that.  I'll do it this way for now on.  Except that it's just bad Blend isn't able to show me the animation normally when there are keyframes like that.  Maybe they are aware it's a bug or maybe we'll live with that until Blend dies

    Thank you again

    Friday, August 17, 2012 4:20 PM
  • Hey Christine, how did you manage to have a shorter link for the skydrive video.  I always end up with something like that

    https://skydrive.live.com/?cid=513b70517e544edb&id=513B70517E544EDB%21512&sff=1#cid=7056CFFE05236B7D&id=7056CFFE05236B7D%21574

    I right clicked everywhere, checked in all menus, did not find it


    • Edited by GearWorld Friday, August 17, 2012 4:26 PM
    Friday, August 17, 2012 4:25 PM
  • Oh found it.  It's in Share there's a GET LINK and a SHORTEN button.  NOT OBVIOUS AT ALL

    http://sdrv.ms/S1R49b

    • Marked as answer by GearWorld Friday, August 17, 2012 4:59 PM
    • Unmarked as answer by GearWorld Friday, August 17, 2012 4:59 PM
    Friday, August 17, 2012 4:29 PM
  • I may be reading this wrong, but to accomplish your 2 second delay before your animation begins, did you try just using BeginTime yet? Might make things easier?


    Please mark answers as helpful when used, and answered when completed.



    Friday, August 17, 2012 4:33 PM
  • I succeeded with the video shown which is to just add a keyframe at 0 and start your animation then after you can move your time in the timeline
    BeginTime ah ? Is this another option ?

    Friday, August 17, 2012 4:43 PM
  • Well I just tried and here the code however the animation doesn't start after 2 seconds.
    It starts immediately

    <VisualStateGroup x:Name="LanguageChoice" ei:ExtendedVisualStateManager.UseFluidLayout="True">
        <VisualStateGroup.Transitions>
        	<VisualTransition GeneratedDuration="0:0:0.5">
        		<VisualTransition.GeneratedEasingFunction>
        			<ExponentialEase EasingMode="EaseInOut" Exponent="5"/>
        		</VisualTransition.GeneratedEasingFunction>
        	</VisualTransition>
        </VisualStateGroup.Transitions>
        <VisualState x:Name="Normal"/>
        <VisualState x:Name="ShowLanguageChoice">
        	<Storyboard BeginTime="0:0:2">
        		<DoubleAnimation Duration="0" To="0.995" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="lstLanguage" d:IsOptimized="True"/>
        		<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="lstLanguage" d:IsOptimized="True"/>
        	</Storyboard>
        </VisualState>
    </VisualStateGroup>


    • Edited by GearWorld Friday, August 17, 2012 4:49 PM
    Friday, August 17, 2012 4:47 PM
  • It's how I specifically set a delay before a timeline begins since that's its purpose. Hence;

    <Storyboard BeginTime="0:0:2" x:Name="myStoryboard">

    ............

    Or apply it directly to your DoubleAnimation, check out the example on the documentation in the link provided as where its applied is relative.



    Please mark answers as helpful when used, and answered when completed.




    Friday, August 17, 2012 4:50 PM
  • I don't believe it will work with a VisualState as the timing for the VisualStateManager seems to override it.

    If you put your animation in a Storyboard and don't use VisualStateManager, K.S.'s suggestion will work.

    You could also set your GoToStateAction on a TimerTrigger...

    		<i:Interaction.Triggers>
    			<ei:TimerTrigger MillisecondsPerTick="2000" TotalTicks="1">
    				<ei:GoToStateAction StateName="VisualState"/>
    			</ei:TimerTrigger>
    		</i:Interaction.Triggers>

     Anyways, it looks like the others have you covered.  Have a great weekend and I hope you get it all worked out quickly and easily.

    ~Christine


    My Gallery

    • Marked as answer by GearWorld Friday, August 17, 2012 4:59 PM
    Friday, August 17, 2012 4:58 PM
  • Fantastic, you're a kind person.
    Have a nice one too.

    Friday, August 17, 2012 5:00 PM
  • Here is a trigger that is the same as an EventTrigger, but also has a delay when the event is fired. To use it, add a new trigger to your application through the file new command, then copy this code into it. Compile, then with your behavior selected, change the trigger type by selecting new, and picking the new type (DelayEventTrigger). You can then use it just like a normal EventTrigger in Blend, but you can specify a delay value in seconds.

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    using System.Windows.Interactivity;
    using System.Windows.Threading;
    
    namespace SilverlightApplication4
    {
    	public class DelayEventTrigger : System.Windows.Interactivity.EventTrigger
    	{
            public DelayEventTrigger()
            {
                this.timer = new DispatcherTimer();
                this.timer.Tick += new EventHandler(timer_Tick);
            }
    
            public double Delay
            {
                get { return (double)GetValue(DelayProperty); }
                set { SetValue(DelayProperty, value); }
            }
    
            public static readonly DependencyProperty DelayProperty =
                DependencyProperty.Register("Delay", typeof(double), typeof(DelayEventTrigger), new PropertyMetadata(1.0));
    
            private DispatcherTimer timer;
    
            protected override void OnEvent(EventArgs eventArgs)
            {
                this.timer.Interval = TimeSpan.FromSeconds(this.Delay);
                this.timer.Start();
            }
    
            void timer_Tick(object sender, EventArgs e)
            {
                this.timer.Stop();
                this.InvokeActions(null);
            }
    	}
    }

    Friday, August 17, 2012 6:29 PM
    Moderator