locked
How to disable the SkipForwardBtn when the story board reaches its end RRS feed

  • Question

  • Given the following codes I wan't to disable the SkipForwardBtn when the story board reaches its end which is by 00:03:02 just like what happens when the SkipBackBtn is disabled at 00:00:00.... hope you can help....

     codes credit to: Christine L. _

    using System;
    using System.Windows;
    using System.Windows.Media.Animation;
    
    namespace WpfApplication30
    {
    	public partial class MainWindow : Window
    	{
    		Storyboard sb = new Storyboard();
    		
    		public MainWindow()
    		{
    			this.InitializeComponent();
    		}
    		
    		private void Window_Loaded(object sender, System.Windows.RoutedEventArgs e)
    		{
    			sb = this.TryFindResource("Storyboard1") as Storyboard;
    		}
    
    		private void PlayBtn_Click(object sender, System.Windows.RoutedEventArgs e)
    		{
    			sb.Begin();
    		}
    
    		private void SkipForwardBtn_Click(object sender, System.Windows.RoutedEventArgs e)
    		{
    			sb.Pause();
    			TimeSpan ts = sb.GetCurrentTime();
    			double a = ts.Seconds + 3;
                		sb.SeekAlignedToLastTick(TimeSpan.FromSeconds(a));
    			sb.Resume();
    		}
    
    		private void SkipBackBtn_Click(object sender, System.Windows.RoutedEventArgs e)
    		{
    			sb.Pause();
    			TimeSpan ts = sb.GetCurrentTime();
    			int a = ts.Seconds - 3;
    			if (a < 0)
    			{
    				button4.IsEnabled = false;
    			}
    			else  
    
    		{
    
    				sb.SeekAlignedToLastTick(TimeSpan.FromSeconds(a));
    				sb.Resume();
    
    
    		}
    	}
    }


    • Edited by Mitche0027 Friday, September 7, 2012 8:33 AM
    Friday, September 7, 2012 8:32 AM

Answers

  • I have updated my sample to try to reproduce and address the issues you were having.

    First of all I extended my storyboard to 4 minutes and set the Duration in the XAML to Duration="0:4:0".

    Here is the xaml...

    <Window
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    	x:Class="WpfApplication30.MainWindow"
    	x:Name="Window"
    	Title="MainWindow"
    	Width="640" Height="480" Loaded="Window_Loaded">
    	<Window.Resources>
    		<Storyboard x:Key="Storyboard1" Duration="0:4:0">
    			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="rectangle">
    				<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
    				<EasingDoubleKeyFrame KeyTime="0:1:0" Value="520"/>
    				<EasingDoubleKeyFrame KeyTime="0:2:0" Value="520"/>
    				<EasingDoubleKeyFrame KeyTime="0:3:0" Value="0"/>
    			</DoubleAnimationUsingKeyFrames>
    			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="rectangle">
    				<EasingDoubleKeyFrame KeyTime="0:1:0" Value="0"/>
    				<EasingDoubleKeyFrame KeyTime="0:2:0" Value="340"/>
    				<EasingDoubleKeyFrame KeyTime="0:3:0" Value="340"/>
    				<EasingDoubleKeyFrame KeyTime="0:4:0" Value="0"/>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    	</Window.Resources>
    	<Grid x:Name="LayoutRoot">
    		<Rectangle x:Name="rectangle" 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>
    		<StackPanel HorizontalAlignment="Center" Margin="0" Orientation="Horizontal" VerticalAlignment="Center">
    			<Button x:Name="PlayBtn" Content="Play" HorizontalAlignment="Right" Width="75" Margin="5,0" Click="PlayBtn_Click"/>
    			<Button x:Name="SkipBackBtn" Content="&lt;" HorizontalAlignment="Right" Width="75" Margin="5,0" Click="SkipBackBtn_Click" />
    			<Button x:Name="SkipForwardBtn" Content="&gt;" HorizontalAlignment="Right" Width="75" Margin="5,0" Click="SkipForwardBtn_Click"/>
    		</StackPanel>
    		<!--Just stuff added for testing.  :) Didn't want to wait 4 minutes so added the extraButton.-->
    		<TextBlock x:Name="tb" TextWrapping="Wrap" Margin="184.5,0,184.5,189.56" VerticalAlignment="Bottom" TextAlignment="Right"/>
    		<Button x:Name="extraButton" Content="Skip forward to 235 seconds" VerticalAlignment="Bottom" Margin="184.5,0,184.5,142.04" Click="Button_Click"/>
    	</Grid>
    </Window>

    As you pointed out, ts.seconds was not accounting for minutes so I used a parse method.  I also added the CurrentTimeInvalidate method to the storyboard to keep track of which buttons should be enabled when...

    using System; using System.Windows; using System.Windows.Media.Animation; namespace WpfApplication30 { public partial class MainWindow : Window { Storyboard sb = new Storyboard(); public MainWindow() { this.InitializeComponent(); SkipBackBtn.IsEnabled = false; SkipForwardBtn.IsEnabled = false; } private void Window_Loaded(object sender, System.Windows.RoutedEventArgs e) { sb = this.TryFindResource("Storyboard1") as Storyboard; sb.CurrentTimeInvalidated += sbCurrentTimeInvalidate; sb.Completed += sbComplete; } private void PlayBtn_Click(object sender, System.Windows.RoutedEventArgs e) { sb.Begin(); } private void SkipForwardBtn_Click(object sender, System.Windows.RoutedEventArgs e) { sb.Pause(); TimeSpan ts = sb.GetCurrentTime(); //As you pointed out the ts.Seconds was not accounting for minutes. //So using the parse method to convert minutes to seconds. double a = TimeSpan.Parse(ts.ToString()).TotalSeconds + 3; sb.SeekAlignedToLastTick(TimeSpan.FromSeconds(a)); sb.Resume(); } private void SkipBackBtn_Click(object sender, System.Windows.RoutedEventArgs e) { sb.Pause(); TimeSpan ts = sb.GetCurrentTime(); double a = TimeSpan.Parse(ts.ToString()).TotalSeconds - 3; if (a > 0) { sb.SeekAlignedToLastTick(TimeSpan.FromSeconds(a)); sb.Resume(); } else //Reset to 0 sb.Begin(); } private void sbCurrentTimeInvalidate(object sender, EventArgs e) {

    //You probably don't need sbClock. But added if you do.

    Clock sbClock = (Clock)sender; TimeSpan ts = sb.GetCurrentTime(); double a = TimeSpan.Parse(ts.ToString()).TotalSeconds; TimeSpan ts2 = sb.Duration.TimeSpan; double b = TimeSpan.Parse(ts2.ToString()).TotalSeconds; if (a >= 3) SkipBackBtn.IsEnabled = true; else SkipBackBtn.IsEnabled = false; if ((a > 0) && (a < (b-3))) SkipForwardBtn.IsEnabled = true; else SkipForwardBtn.IsEnabled = false; tb.Text = b + "/" + a + "/" +sbClock.CurrentTime.ToString(); } private void sbComplete(object sender, EventArgs e) { sb.Stop(); PlayBtn.IsEnabled = true; SkipBackBtn.IsEnabled = false; SkipForwardBtn.IsEnabled = false; } private void Button_Click(object sender, System.Windows.RoutedEventArgs e) { //This method and corresponding button were only added because I didn't want //to wait for a 4 minute storyboard to near it's end. sb.Pause(); sb.SeekAlignedToLastTick(TimeSpan.FromSeconds(235)); sb.Resume(); } } }


    Let me know if that helps.  I'm not sure about the "storyboard repeating itself when it reaches 60 seconds".  I didn't experience this and parsing the TimeSpan may have addressed it.  Let me know if not.

    Sample Project Uploaded to Skydrive:  http://sdrv.ms/QlrQEB

    ~Christine


    My Gallery



    • Edited by Christine L. _ Friday, September 7, 2012 11:29 PM
    • Marked as answer by Mitche0027 Monday, September 10, 2012 9:30 AM
    Friday, September 7, 2012 11:15 PM

All replies

  • Hello Mitche.

    One way to go about this would be to add a Storyboard.Completed event...

    private void Window_Loaded(object sender, System.Windows.RoutedEventArgs e)
    		{
    			Storyboard sb = this.TryFindResource("Storyboard1") as Storyboard;
    			sb.Completed += DisableButton;
    		}
    		
    		private void DisableButton(object sender, EventArgs e)
    		{
    			btn1.IsEnabled = false;
    		}

    You could also use the built-in "CallMethodAction" and change the trigger to StoryboardCompleted.

    Hope that helps.

    ~Christine


    My Gallery


    • Edited by Christine L. _ Friday, September 7, 2012 12:20 PM
    • Marked as answer by Mitche0027 Friday, September 7, 2012 1:14 PM
    • Unmarked as answer by Mitche0027 Friday, September 7, 2012 1:49 PM
    Friday, September 7, 2012 12:19 PM
  • thank you for always helping me Christine... the codes worked... when the storyboard was suppose to end btn1 was disabled... but I found another error from the previous code... when the story board reaches 60 second the codes

    double a = ts.Seconds + 3;
    would force the storyboard to start over again.... 

    Since my storyboard runs at 00:03:02... I tried using the minutes scale... I changed the code into:

    double a = ts.Minutes + 1;

    and it worked.... It didn't loop back to the beginning of the storyboard and continued to the next storyboard...unfortunately I had to sacrifice the +3 second function so I rewrote the code to:

    double a = ts.Minutes = 0.05 // which is equals to 3 seconds;

    then I discovered that ts.Minutes does execute values less than 0

    is it possible to stop the storyboard repeating itself when it reaches 60 seconds?

    sorry for asking too much...

    • Edited by Mitche0027 Friday, September 7, 2012 3:59 PM
    Friday, September 7, 2012 1:13 PM
  • I have updated my sample to try to reproduce and address the issues you were having.

    First of all I extended my storyboard to 4 minutes and set the Duration in the XAML to Duration="0:4:0".

    Here is the xaml...

    <Window
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    	x:Class="WpfApplication30.MainWindow"
    	x:Name="Window"
    	Title="MainWindow"
    	Width="640" Height="480" Loaded="Window_Loaded">
    	<Window.Resources>
    		<Storyboard x:Key="Storyboard1" Duration="0:4:0">
    			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="rectangle">
    				<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
    				<EasingDoubleKeyFrame KeyTime="0:1:0" Value="520"/>
    				<EasingDoubleKeyFrame KeyTime="0:2:0" Value="520"/>
    				<EasingDoubleKeyFrame KeyTime="0:3:0" Value="0"/>
    			</DoubleAnimationUsingKeyFrames>
    			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="rectangle">
    				<EasingDoubleKeyFrame KeyTime="0:1:0" Value="0"/>
    				<EasingDoubleKeyFrame KeyTime="0:2:0" Value="340"/>
    				<EasingDoubleKeyFrame KeyTime="0:3:0" Value="340"/>
    				<EasingDoubleKeyFrame KeyTime="0:4:0" Value="0"/>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    	</Window.Resources>
    	<Grid x:Name="LayoutRoot">
    		<Rectangle x:Name="rectangle" 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>
    		<StackPanel HorizontalAlignment="Center" Margin="0" Orientation="Horizontal" VerticalAlignment="Center">
    			<Button x:Name="PlayBtn" Content="Play" HorizontalAlignment="Right" Width="75" Margin="5,0" Click="PlayBtn_Click"/>
    			<Button x:Name="SkipBackBtn" Content="&lt;" HorizontalAlignment="Right" Width="75" Margin="5,0" Click="SkipBackBtn_Click" />
    			<Button x:Name="SkipForwardBtn" Content="&gt;" HorizontalAlignment="Right" Width="75" Margin="5,0" Click="SkipForwardBtn_Click"/>
    		</StackPanel>
    		<!--Just stuff added for testing.  :) Didn't want to wait 4 minutes so added the extraButton.-->
    		<TextBlock x:Name="tb" TextWrapping="Wrap" Margin="184.5,0,184.5,189.56" VerticalAlignment="Bottom" TextAlignment="Right"/>
    		<Button x:Name="extraButton" Content="Skip forward to 235 seconds" VerticalAlignment="Bottom" Margin="184.5,0,184.5,142.04" Click="Button_Click"/>
    	</Grid>
    </Window>

    As you pointed out, ts.seconds was not accounting for minutes so I used a parse method.  I also added the CurrentTimeInvalidate method to the storyboard to keep track of which buttons should be enabled when...

    using System; using System.Windows; using System.Windows.Media.Animation; namespace WpfApplication30 { public partial class MainWindow : Window { Storyboard sb = new Storyboard(); public MainWindow() { this.InitializeComponent(); SkipBackBtn.IsEnabled = false; SkipForwardBtn.IsEnabled = false; } private void Window_Loaded(object sender, System.Windows.RoutedEventArgs e) { sb = this.TryFindResource("Storyboard1") as Storyboard; sb.CurrentTimeInvalidated += sbCurrentTimeInvalidate; sb.Completed += sbComplete; } private void PlayBtn_Click(object sender, System.Windows.RoutedEventArgs e) { sb.Begin(); } private void SkipForwardBtn_Click(object sender, System.Windows.RoutedEventArgs e) { sb.Pause(); TimeSpan ts = sb.GetCurrentTime(); //As you pointed out the ts.Seconds was not accounting for minutes. //So using the parse method to convert minutes to seconds. double a = TimeSpan.Parse(ts.ToString()).TotalSeconds + 3; sb.SeekAlignedToLastTick(TimeSpan.FromSeconds(a)); sb.Resume(); } private void SkipBackBtn_Click(object sender, System.Windows.RoutedEventArgs e) { sb.Pause(); TimeSpan ts = sb.GetCurrentTime(); double a = TimeSpan.Parse(ts.ToString()).TotalSeconds - 3; if (a > 0) { sb.SeekAlignedToLastTick(TimeSpan.FromSeconds(a)); sb.Resume(); } else //Reset to 0 sb.Begin(); } private void sbCurrentTimeInvalidate(object sender, EventArgs e) {

    //You probably don't need sbClock. But added if you do.

    Clock sbClock = (Clock)sender; TimeSpan ts = sb.GetCurrentTime(); double a = TimeSpan.Parse(ts.ToString()).TotalSeconds; TimeSpan ts2 = sb.Duration.TimeSpan; double b = TimeSpan.Parse(ts2.ToString()).TotalSeconds; if (a >= 3) SkipBackBtn.IsEnabled = true; else SkipBackBtn.IsEnabled = false; if ((a > 0) && (a < (b-3))) SkipForwardBtn.IsEnabled = true; else SkipForwardBtn.IsEnabled = false; tb.Text = b + "/" + a + "/" +sbClock.CurrentTime.ToString(); } private void sbComplete(object sender, EventArgs e) { sb.Stop(); PlayBtn.IsEnabled = true; SkipBackBtn.IsEnabled = false; SkipForwardBtn.IsEnabled = false; } private void Button_Click(object sender, System.Windows.RoutedEventArgs e) { //This method and corresponding button were only added because I didn't want //to wait for a 4 minute storyboard to near it's end. sb.Pause(); sb.SeekAlignedToLastTick(TimeSpan.FromSeconds(235)); sb.Resume(); } } }


    Let me know if that helps.  I'm not sure about the "storyboard repeating itself when it reaches 60 seconds".  I didn't experience this and parsing the TimeSpan may have addressed it.  Let me know if not.

    Sample Project Uploaded to Skydrive:  http://sdrv.ms/QlrQEB

    ~Christine


    My Gallery



    • Edited by Christine L. _ Friday, September 7, 2012 11:29 PM
    • Marked as answer by Mitche0027 Monday, September 10, 2012 9:30 AM
    Friday, September 7, 2012 11:15 PM
  • thank you Christine... you've help me once again... it did solve my problem but I made a little adjustments to fit my needs... I didn't add the sb clock by the way..

    for future reference here is the codes:

     private void button4_Click(object sender, System.Windows.RoutedEventArgs e)
            {
            	// TODO: for the next button
                Storyboard sb1 = this.TryFindResource("sb16") as Storyboard;
                sb1.Pause();
                TimeSpan ts = sb1.GetCurrentTime();
                double a = TimeSpan.Parse(ts.ToString()).TotalSeconds + 3;
    
                sb1.SeekAlignedToLastTick(TimeSpan.FromSeconds(a));
                sb1.Resume();
    
                if (a >= 0)
                {
                    button4.IsEnabled = true;
                }
                else if (a < 0)
                {
                    button4.IsEnabled = false;
                }
                else
                { }
            }
    
            private void button5_Click(object sender, System.Windows.RoutedEventArgs e)
            {
            	// this is for the previous button
                Storyboard sb1 = this.TryFindResource("sb16") as Storyboard;
                sb1.Pause();
                TimeSpan ts = sb1.GetCurrentTime();
                double b = TimeSpan.Parse(ts.ToString()).TotalSeconds - 3;
    
    
                if (b <= 3)
                {
    
                    button5.IsEnabled = false;
                }
                else if (b > 3)
                {
                    sb1.SeekAlignedToLastTick(TimeSpan.FromSeconds(b));
                    sb1.Resume();
                    button5.IsEnabled = true;
                }
    
                else
                {
    
                }
    
    	}

    Monday, September 10, 2012 9:33 AM