locked
how can I pause a wpf storyboard using C# code behind? RRS feed

  • Question

  • scene1 automatically starts when the form loads... I want to stop it manually using C# code behind through the a button named skip and at the same time play scene2... Is that possible? 

    <Window.Resources>
        <Storyboard x:Key="scene1">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="whitebox">
                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                <EasingDoubleKeyFrame KeyTime="0:0:1.7" Value="0"/>
            </DoubleAnimationUsingKeyFrames>
            <StringAnimationUsingKeyFrames 
    
    ----------------------> beginning codes only... the code goes on very very very long.......

    Wednesday, June 27, 2012 10:14 AM

Answers

  • thanks a lot for taking the time to help me out.... I ready did paused scene1 but the problem is a error popped out after... It is directed to :

    sb.Pause();

    stating that ---> Object reference not set to an instance of an object.

    • Marked as answer by Mitche0027 Saturday, August 25, 2012 1:03 PM
    Wednesday, June 27, 2012 2:42 PM
  • It really helped a lot... thank you very much :) instead of stop I declared storyboard1.pause(); it did what I wanted but an error occur after pointing to:

       storyboard1.Pause();

    stating that ---> Object reference not set to an instance of an object.

    • Edited by Mitche0027 Wednesday, June 27, 2012 2:47 PM
    • Marked as answer by Mitche0027 Saturday, August 25, 2012 1:03 PM
    Wednesday, June 27, 2012 2:43 PM

All replies

  • Here's one way.

    XAML:

    <Window
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    	x:Class="WpfApplication4.MainWindow"
    	x:Name="Window"
    	Title="MainWindow"
    	Width="640" Height="480">
    	<Window.Resources>
    		<Storyboard x:Key="Storyboard1">
    			<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="rectangle">
    				<EasingColorKeyFrame KeyTime="0:0:5" Value="#FF11117A"/>
    			</ColorAnimationUsingKeyFrames>
    		</Storyboard>
    		<Storyboard x:Key="Storyboard2">
    			<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="rectangle">
    				<EasingColorKeyFrame KeyTime="0:0:1" Value="Red"/>
    			</ColorAnimationUsingKeyFrames>
    		</Storyboard>
    	</Window.Resources>
    
    	<Grid x:Name="LayoutRoot">
    		<Rectangle x:Name="rectangle" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="100" Stroke="Black" VerticalAlignment="Top" Width="100"/>
    		<Button Content="Start" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="125,48,0,0">
    			<i:Interaction.Triggers>
    				<i:EventTrigger EventName="Click">
    					<ei:ControlStoryboardAction Storyboard="{StaticResource Storyboard1}"/>
    				</i:EventTrigger>
    			</i:Interaction.Triggers>
    		</Button>
    		<Button Content="Skip" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="221,48,0,0" Click="Skip_Click">
    		</Button>
    	</Grid>
    </Window>

    Code-behind (C#):

    using System.Windows;
    using System.Windows.Media.Animation;
    
    namespace WpfApplication4
    {
    	/// <summary>
    	/// Interaction logic for MainWindow.xaml
    	/// </summary>
    	public partial class MainWindow : Window
    	{
    		public MainWindow()
    		{
    			this.InitializeComponent();
    
    			// Insert code required on object creation below this point.
    		}
    
    		private void Skip_Click(object sender, System.Windows.RoutedEventArgs e)
    		{
                Storyboard storyboard1 = (Storyboard)this.Resources["Storyboard1"];
                storyboard1.Stop();
    
                Storyboard storyboard2 = (Storyboard)this.Resources["Storyboard2"];
                storyboard2.Begin();
    		}
    	}
    }
    Hope that helps.
    • Proposed as answer by Brian Hilstrom Wednesday, June 27, 2012 2:03 PM
    Wednesday, June 27, 2012 2:03 PM
  • Hello Mitche.

    When I am working with storyboards in code behind it has been my experience that I need to do all the controlling from code or with triggers, but I can never seem to get triggers and code to work well together.

    Here is a sample...

    using System.Windows;
    using System.Windows.Media.Animation;
    namespace WpfApplication20
    {
    	public partial class MainWindow : Window
    	{
    		public MainWindow()
    		{
    			this.InitializeComponent();
    		}
    		private void Window_Loaded(object sender, System.Windows.RoutedEventArgs e)
    		{
    			Storyboard sb = this.TryFindResource("scene1") as Storyboard;
    			sb.Begin();
    		}
    		private void skipBtn_Click(object sender, System.Windows.RoutedEventArgs e)
    		{
    			Storyboard sb = this.TryFindResource("scene1") as Storyboard;
    			sb.Pause();
    			Storyboard sb2 = this.TryFindResource("scene2") as Storyboard;
    			sb2.Begin();
    		}
    	}
    }

    and the xaml...

    <Window
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    	x:Class="WpfApplication20.MainWindow"
    	x:Name="Window"
    	Title="MainWindow"
    	Width="640" Height="480" Loaded="Window_Loaded">
    	<Window.Resources>
    		<Storyboard x:Key="scene1" AutoReverse="True" RepeatBehavior="Forever">
    			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="aBox">
    				<EasingDoubleKeyFrame KeyTime="0:0:1" Value="520"/>
    			</DoubleAnimationUsingKeyFrames>
    			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="aBox">
    				<EasingDoubleKeyFrame KeyTime="0:0:1" Value="298"/>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    		<Storyboard x:Key="scene2" RepeatBehavior="Forever" AutoReverse="True">
    			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="aBox">
    				<EasingDoubleKeyFrame KeyTime="0" Value="516"/>
    				<EasingDoubleKeyFrame KeyTime="0:0:1" Value="3"/>
    			</DoubleAnimationUsingKeyFrames>
    			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="aBox">
    				<EasingDoubleKeyFrame KeyTime="0" Value="8"/>
    				<EasingDoubleKeyFrame KeyTime="0:0:1" Value="282"/>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    	</Window.Resources>
    	<Grid x:Name="LayoutRoot">
    		<Rectangle x:Name="aBox" Fill="Blue" HorizontalAlignment="Left" Height="100" Stroke="Black" VerticalAlignment="Top" Width="100" RenderTransformOrigin="0.5,0.5">
    			<Rectangle.RenderTransform>
    				<TransformGroup>
    					<ScaleTransform/>
    					<SkewTransform/>
    					<RotateTransform/>
    					<TranslateTransform/>
    				</TransformGroup>
    			</Rectangle.RenderTransform>
    		</Rectangle>
    		<Button x:Name="skipBtn" Content="Skip" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="75" Margin="8,0,0,8" Click="skipBtn_Click"/>
    	</Grid>
    </Window>

    You could also put the ControlStoryboardAction on your button twice.  Once to stop scene1 and once to begin scene2, if you didn't really need to go to code.

    Which would change the button xaml to...

    <Button x:Name="skipBtn" Content="Skip" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="75" Margin="8,0,0,8">
    			<i:Interaction.Triggers>
    				<i:EventTrigger EventName="Click">
    					<ei:ControlStoryboardAction ControlStoryboardOption="Stop" Storyboard="{StaticResource scene1}"/>
    					<ei:ControlStoryboardAction Storyboard="{StaticResource scene2}"/>
    				</i:EventTrigger>
    			</i:Interaction.Triggers>
    		</Button>

    There is a nice storyboard overview here... http://msdn.microsoft.com/en-us/library/ms742868.aspx

    and a list of the storyboard methods... http://msdn.microsoft.com/en-us/library/system.windows.media.animation.storyboard_methods

    ~Christine

    @Brian... LOL Sorry Brian I had this open and didn't see you had answered.  Your answer was most certainly the correct one. :)

    My Gallery


    Wednesday, June 27, 2012 2:07 PM
  • thanks a lot for taking the time to help me out.... I ready did paused scene1 but the problem is a error popped out after... It is directed to :

    sb.Pause();

    stating that ---> Object reference not set to an instance of an object.

    • Marked as answer by Mitche0027 Saturday, August 25, 2012 1:03 PM
    Wednesday, June 27, 2012 2:42 PM
  • It really helped a lot... thank you very much :) instead of stop I declared storyboard1.pause(); it did what I wanted but an error occur after pointing to:

       storyboard1.Pause();

    stating that ---> Object reference not set to an instance of an object.

    • Edited by Mitche0027 Wednesday, June 27, 2012 2:47 PM
    • Marked as answer by Mitche0027 Saturday, August 25, 2012 1:03 PM
    Wednesday, June 27, 2012 2:43 PM
  • You need to be sure the string used to find the resource by name matches the name of the storyboard as declared in xaml, for example "Storyboard1"
    Wednesday, June 27, 2012 4:17 PM
    Moderator
  • success! it's now working great thank you very much for the help~

    Thursday, June 28, 2012 2:42 AM
  • Hello,

    a pure code behind way of solution: One could also use an AnimationClock and control the different states of the storyboard by using the Clock.Controller.

    Regards,

    Martin

    Tuesday, July 3, 2012 7:07 AM
  • Hello Mitche.

    When I am working with storyboards in code behind it has been my experience that I need to do all the controlling from code or with triggers, but I can never seem to get triggers and code to work well together.

    Here is a sample...

    using System.Windows;
    using System.Windows.Media.Animation;
    namespace WpfApplication20
    {
    	public partial class MainWindow : Window
    	{
    		public MainWindow()
    		{
    			this.InitializeComponent();
    		}
    		private void Window_Loaded(object sender, System.Windows.RoutedEventArgs e)
    		{
    			Storyboard sb = this.TryFindResource("scene1") as Storyboard;
    			sb.Begin();
    		}
    		private void skipBtn_Click(object sender, System.Windows.RoutedEventArgs e)
    		{
    			Storyboard sb = this.TryFindResource("scene1") as Storyboard;
    			sb.Pause();
    			Storyboard sb2 = this.TryFindResource("scene2") as Storyboard;
    			sb2.Begin();
    		}
    	}
    }

    and the xaml...

    <Window
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    	x:Class="WpfApplication20.MainWindow"
    	x:Name="Window"
    	Title="MainWindow"
    	Width="640" Height="480" Loaded="Window_Loaded">
    	<Window.Resources>
    		<Storyboard x:Key="scene1" AutoReverse="True" RepeatBehavior="Forever">
    			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="aBox">
    				<EasingDoubleKeyFrame KeyTime="0:0:1" Value="520"/>
    			</DoubleAnimationUsingKeyFrames>
    			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="aBox">
    				<EasingDoubleKeyFrame KeyTime="0:0:1" Value="298"/>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    		<Storyboard x:Key="scene2" RepeatBehavior="Forever" AutoReverse="True">
    			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="aBox">
    				<EasingDoubleKeyFrame KeyTime="0" Value="516"/>
    				<EasingDoubleKeyFrame KeyTime="0:0:1" Value="3"/>
    			</DoubleAnimationUsingKeyFrames>
    			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="aBox">
    				<EasingDoubleKeyFrame KeyTime="0" Value="8"/>
    				<EasingDoubleKeyFrame KeyTime="0:0:1" Value="282"/>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    	</Window.Resources>
    	<Grid x:Name="LayoutRoot">
    		<Rectangle x:Name="aBox" Fill="Blue" HorizontalAlignment="Left" Height="100" Stroke="Black" VerticalAlignment="Top" Width="100" RenderTransformOrigin="0.5,0.5">
    			<Rectangle.RenderTransform>
    				<TransformGroup>
    					<ScaleTransform/>
    					<SkewTransform/>
    					<RotateTransform/>
    					<TranslateTransform/>
    				</TransformGroup>
    			</Rectangle.RenderTransform>
    		</Rectangle>
    		<Button x:Name="skipBtn" Content="Skip" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="75" Margin="8,0,0,8" Click="skipBtn_Click"/>
    	</Grid>
    </Window>

    You could also put the ControlStoryboardAction on your button twice.  Once to stop scene1 and once to begin scene2, if you didn't really need to go to code.

    Which would change the button xaml to...

    <Button x:Name="skipBtn" Content="Skip" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="75" Margin="8,0,0,8">
    			<i:Interaction.Triggers>
    				<i:EventTrigger EventName="Click">
    					<ei:ControlStoryboardAction ControlStoryboardOption="Stop" Storyboard="{StaticResource scene1}"/>
    					<ei:ControlStoryboardAction Storyboard="{StaticResource scene2}"/>
    				</i:EventTrigger>
    			</i:Interaction.Triggers>
    		</Button>

    There is a nice storyboard overview here... http://msdn.microsoft.com/en-us/library/ms742868.aspx

    and a list of the storyboard methods... http://msdn.microsoft.com/en-us/library/system.windows.media.animation.storyboard_methods

    ~Christine

    @Brian... LOL Sorry Brian I had this open and didn't see you had answered.  Your answer was most certainly the correct one. :)

    My Gallery


    A BEAUTIFUL answer that completely solved ALL my problems!  

    I now have "toaster style" pop up notifications that can be configured to show anywhere the user wants on screen and includes a queue system for a seemingly infinite number of notifications to display, one at a time.  You can also mouse over the notification to 'seek' back to the beginning of the storyboard and PAUSE right there, then resume when you mouse off. The storyboard is simply and opacity fade so when the notification starts fading out and you mouse-over, it instantly restores to full opacity and waits for the mouse to leave before starting to fade again.  I can share my code if anyone wants it!

    Wednesday, January 15, 2014 6:42 PM