Unanswered Slide Show Question

  • Monday, December 03, 2012 10:46 PM
     
     

    Greetings to all,

    I'm trying to create a slide show of 5 images almost identical to that seen on this link http://www.newpaltz.edu/

    I've been able to create a slide show using storyboard where the images slide in/out over a time interval. I've been able to create the buttons with states to a specific image. The problem I've been running into is this:

    When the storyboard loads with the page the storyboard is set to loop forever. So when I click on one of the buttons the specify image appears but the storyboard continues to play. I guess what I'm asking is there a way to shut off the storyboard when the user clicks the buttons. My second question is, the concept of a slide show is very common, why aren't there any tutorials to show how this done?

    I've posted here as a last resort since I've researched possible solutions first before coming here.

    Thank you for your time and effort.

All Replies

  • Tuesday, December 04, 2012 1:35 AM
     
     

    Hello MikeyN.

    What kind of a project are you creating?  Silverlight, WPF or WP7?

    How are you starting your storyboard when the page loads?  With a trigger?  From Code-Behind?

    Should the storyboard resume after a certain amount of time or on an event?

    For a basic answer... you could call the Storyboard.Pause() on the button click event and call Storyboard.Resume() after a certain amount of time or on MouseLeave.

    Not so long ago I helped someone with manipulating storyboards in this thread... http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/b07c758f-caae-4e7c-8986-33ea963a5929

    Ultimately, we ended up with the following sample project which I have posted to my SkyDrive... http://sdrv.ms/QlrQEB

    I also have a Silverlight SlideShow example on my SkyDrive I had done for someone last year or so...  http://sdrv.ms/Uelnrk  It may give you some ideas.

    ~Christine

    Edit... The SL SlideShow example I gave deals more with lists.  This is a sample page banner... http://sdrv.ms/TyH2eo 

    I had also added one to the Expression Gallery... http://gallery.expression.microsoft.com/PageBanner  If you read the comments, Martin gives a link to one he had created and Martin always turns out incredible work.  You may also want to search the Gallery for other examples.


    My Gallery - calControls


  • Tuesday, December 04, 2012 4:06 AM
     
     

    Christine thank you for the response, you've helped out in the past.

    My project is a Silverlight + Website application. All my images are on a Pathlistbox, which I am controlling with a storyboard that is looped forever. I'm trying to recreate a slide show as shown from this link http://www.newpaltz.edu/ . I wish to have buttons act as a quick link to a particular slide on the show.

  • Tuesday, December 04, 2012 5:01 PM
     
      Has Code

    Well based on how I think you may have set it up, here is the sample I came up with...

    <UserControl
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    	xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
    	xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
    	xmlns:ec="http://schemas.microsoft.com/expression/2010/controls" mc:Ignorable="d"
    	x:Class="SLSlideShow.MainPage"
    	Width="640" Height="480">
    	<UserControl.Resources>
    		<Storyboard x:Name="Storyboard1" RepeatBehavior="Forever">
    			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(PathListBox.LayoutPaths)[0].(LayoutPath.Start)" Storyboard.TargetName="pathListBox">
    				<EasingDoubleKeyFrame KeyTime="0" Value="0.2">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CircleEase EasingMode="EaseOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="0:0:3" Value="0.2">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CircleEase EasingMode="EaseOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="0:0:4" Value="0">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CircleEase EasingMode="EaseOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="0:0:7" Value="0">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CircleEase EasingMode="EaseOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="0:0:8" Value="-0.2">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CircleEase EasingMode="EaseOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="0:0:11" Value="-0.2">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CircleEase EasingMode="EaseOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="0:0:12" Value="-0.4">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CircleEase EasingMode="EaseOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="0:0:15" Value="-0.4">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CircleEase EasingMode="EaseOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="0:0:16" Value="-0.6">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CircleEase EasingMode="EaseOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="0:0:19" Value="-0.6">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CircleEase EasingMode="EaseOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="0:0:20" Value="-0.8">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CircleEase EasingMode="EaseOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    	</UserControl.Resources>
    
    	<i:Interaction.Triggers>
    		<i:EventTrigger>
    			<ei:ControlStoryboardAction Storyboard="{StaticResource Storyboard1}"/>
    		</i:EventTrigger>
    	</i:Interaction.Triggers>
    
    	<Grid x:Name="LayoutRoot" Background="White">
    		<Canvas HorizontalAlignment="Center" Height="110" VerticalAlignment="Center" Width="110" Background="Black" Clip="M0.5,0.5 L109.5,0.5 L109.5,109.5 L0.5,109.5 z">
    			<Path x:Name="path" Data="M75,234 L572,234" Height="1" Stretch="Fill" UseLayoutRounding="False" Width="540" Stroke="#00000000" Canvas.Left="-52.5" Canvas.Top="55"/>
    			<ec:PathListBox x:Name="pathListBox" HorizontalAlignment="Center" Height="100" VerticalAlignment="Center" Width="100" Canvas.Left="5" Canvas.Top="5">
    				<ec:PathListBox.LayoutPaths>
    					<ec:LayoutPath SourceElement="{Binding ElementName=path}" Distribution="Even" FillBehavior="NoOverlap" Padding="20"/>
    				</ec:PathListBox.LayoutPaths>
    				<Rectangle Fill="Blue" Height="100" Stroke="Black" Width="100"/>
    				<Rectangle Fill="Red" Height="100" Stroke="Black" Width="100"/>
    				<Rectangle Fill="Orange" Height="100" Stroke="Black" Width="100"/>
    				<Rectangle Fill="Green" Height="100" Stroke="Black" Width="100"/>
    				<Rectangle Fill="Yellow" Height="100" Stroke="Black" Width="100"/>
    			</ec:PathListBox>
    		</Canvas>
    		<StackPanel Margin="0,159,0,0" Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Center">
    			<Button Content="Blue" d:LayoutOverrides="Width" Margin="5,0" Tag="1" Click="Button_Click"/>
    			<Button Content="Red" d:LayoutOverrides="Width" Margin="5,0" Tag="2" Click="Button_Click"/>
    			<Button Content="Orange" d:LayoutOverrides="Width" Margin="5,0" Tag="3" Click="Button_Click"/>
    			<Button Content="Green" d:LayoutOverrides="Width" Margin="5,0" Tag="4" Click="Button_Click"/>
    			<Button Content="Yellow" d:LayoutOverrides="Width" Margin="5,0" Tag="5" Click="Button_Click"/>
    		</StackPanel>
    	</Grid>
    </UserControl>

    and the code-behind...

    using System;
    using System.Windows.Controls;
    using System.Windows.Threading;
    
    namespace SLSlideShow
    {
    	public partial class MainPage : UserControl
    	{
    		public MainPage()
    		{
    			InitializeComponent();
    		}
    
    		private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
    		{
    			Button btn = sender as Button;
    			Storyboard1.Pause();
    			
    			int a = Convert.ToInt16(btn.Tag.ToString());
    			
    			if (a == 1) Storyboard1.Seek(TimeSpan.FromSeconds(0));  
    			if (a == 2) Storyboard1.Seek(TimeSpan.FromSeconds(4));  //Need to adjust all these based on your storyboard time.
    			if (a == 3) Storyboard1.Seek(TimeSpan.FromSeconds(8));
    			if (a == 4) Storyboard1.Seek(TimeSpan.FromSeconds(12));
    			if (a == 5) Storyboard1.Seek(TimeSpan.FromSeconds(16));
    			
    			InsertPauseTime();
    			//Storyboard1.Resume();  //Remove InsertPauseTime() and uncomment this line if you don't want the pause.
    		}
    		
    		private void InsertPauseTime()
    		{
    			//This simply creates a pause of 3 seconds before resuming the storyboard.
    			
    			DispatcherTimer dt = new DispatcherTimer();
    			int counter = 0;
    			
    			dt.Tick += delegate
    			{
    				counter++;
    				if (counter == 3)
    				{
    					dt.Stop();
    					Storyboard1.Resume();
    				}
    			};
    			
    			dt.Interval = new TimeSpan(0, 0, 0, 1);
    			dt.Start();
    		}
    	}
    }

    I used rectangles instead of pictures.  I gave each of the buttons a tag ... 1, 2, etc...  You could seek to the desired position in the timeline based on the button content.

    Uploaded to SkyDrive:  SLSlideShow_MikeyN

    Let me know if that helps or if I completely missed the mark and we can try again.

    ~Christine


    My Gallery - calControls

  • Tuesday, December 04, 2012 6:24 PM
     
      Has Code

    Sorry for not posting this sooner, I got caught up with work.  So I hope you look back at this thread.

    Anyways, I created a second sample based on the link you had provided.  I used states instead of a storyboard and did not use a pathListBox.

    <UserControl
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    	xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
    	xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" mc:Ignorable="d"
    	x:Class="SLSlideShow2.MainPage"
    	Width="640" Height="480" Loaded="UserControl_Loaded">
    
    	<Grid x:Name="LayoutRoot" Background="White">
    		<VisualStateManager.VisualStateGroups>
    			<VisualStateGroup x:Name="VisualStateGroup">
    				<VisualStateGroup.Transitions>
    					<VisualTransition GeneratedDuration="0:0:3">
    						<VisualTransition.GeneratedEasingFunction>
    							<CircleEase EasingMode="EaseOut"/>
    						</VisualTransition.GeneratedEasingFunction>
    					</VisualTransition>
    				</VisualStateGroup.Transitions>
    				<VisualState x:Name="State1">
    					<Storyboard/>
    				</VisualState>
    				<VisualState x:Name="State2">
    					<Storyboard>
    						<DoubleAnimation Duration="0" To="-600" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="stackPanel" d:IsOptimized="True"/>
    						<ColorAnimation Duration="0" To="White" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid" d:IsOptimized="True"/>
    						<ColorAnimation Duration="0" To="Orange" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid1" d:IsOptimized="True"/>
    					</Storyboard>
    				</VisualState>
    				<VisualState x:Name="State3">
    					<Storyboard>
    						<DoubleAnimation Duration="0" To="-1200" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="stackPanel" d:IsOptimized="True"/>
    						<ColorAnimation Duration="0" To="White" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid" d:IsOptimized="True"/>
    						<ColorAnimation Duration="0" To="Orange" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid2" d:IsOptimized="True"/>
    					</Storyboard>
    				</VisualState>
    				<VisualState x:Name="State4">
    					<Storyboard>
    						<ColorAnimation Duration="0" To="White" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid" d:IsOptimized="True"/>
    						<ColorAnimation Duration="0" To="Orange" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid3" d:IsOptimized="True"/>
    						<DoubleAnimation Duration="0" To="-1800" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="stackPanel" d:IsOptimized="True"/>
    					</Storyboard>
    				</VisualState>
    				<VisualState x:Name="State5">
    					<Storyboard>
    						<ColorAnimation Duration="0" To="White" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid" d:IsOptimized="True"/>
    						<ColorAnimation Duration="0" To="Orange" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid4" d:IsOptimized="True"/>
    						<DoubleAnimation Duration="0" To="-2400" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="stackPanel" d:IsOptimized="True"/>
    					</Storyboard>
    				</VisualState>
    			</VisualStateGroup>
    		</VisualStateManager.VisualStateGroups>
    		<Canvas HorizontalAlignment="Right" Height="300" VerticalAlignment="Top" Width="600" Clip="M0.5,0.5 L599.5,0.5 L599.5,299.5 L0.5,299.5 z" MouseEnter="Canvas_MouseEnter" MouseLeave="Canvas_MouseLeave">
    			<StackPanel x:Name="stackPanel" Orientation="Horizontal" Height="300" RenderTransformOrigin="0.5,0.5">
    				<StackPanel.RenderTransform>
    					<CompositeTransform/>
    				</StackPanel.RenderTransform>
    				<Rectangle Fill="Blue" Stroke="Black" Width="600" Height="300"/>
    				<Rectangle Fill="Red" Stroke="Black" Width="600" Height="300"/>
    				<Rectangle Fill="Orange" Stroke="Black" Width="600" Height="300"/>
    				<Rectangle Fill="Green" Stroke="Black" Width="600" Height="300"/>
    				<Rectangle Fill="Yellow" Stroke="Black" Width="600" Height="300"/>
    			</StackPanel>
    			<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" Canvas.Left="468">
    				<Grid x:Name="grid" Height="16" Width="16" Background="Orange" Margin="5" Cursor="Hand">
    					<TextBlock TextWrapping="Wrap" Text="1" TextAlignment="Center" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"/>
    				</Grid>
    				<Grid x:Name="grid1" Height="16" Width="16" Background="White" Margin="5" Cursor="Hand">
    					<TextBlock TextWrapping="Wrap" Text="2" TextAlignment="Center" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"/>
    				</Grid>
    				<Grid x:Name="grid2" Height="16" Width="16" Background="White" Margin="5" Cursor="Hand">
    					<TextBlock TextWrapping="Wrap" Text="3" TextAlignment="Center" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"/>
    				</Grid>
    				<Grid x:Name="grid3" Height="16" Width="16" Background="White" Margin="5" Cursor="Hand">
    					<TextBlock TextWrapping="Wrap" Text="4" TextAlignment="Center" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"/>
    				</Grid>
    				<Grid x:Name="grid4" Height="16" Width="16" Background="White" Margin="5" Cursor="Hand">
    					<TextBlock TextWrapping="Wrap" Text="5" TextAlignment="Center" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"/>
    				</Grid>
    			</StackPanel>
    		</Canvas>
    	</Grid>
    </UserControl>

    and the code-behind...

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Threading;
    
    namespace SLSlideShow2
    {
    	public partial class MainPage : UserControl
    	{
    		VisualStateGroup vsg;
    		VisualState currentState;
    		DispatcherTimer dt;
    		
    		public MainPage()
    		{
    			InitializeComponent();
    		}
    
    		private void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
    		{
    			VisualStateManager.GoToState(this, "State1", true);
    			vsg = this.VisualStateGroup;
    			currentState = vsg.States[0] as VisualState;
    			AnimateStates();
    		}
    		
    		private void AnimateStates()
    		{
    			int a = 0;
    			
    			foreach (VisualState vs in vsg.States)
    			{
    				if (vs == currentState)
    					a = vsg.States.IndexOf(vs);				
    			}			
    			StartTimer(a);
    		}
    		
    		private void StartTimer(int a)
    		{
    			dt = new DispatcherTimer();
    			int counter = 0;
    			
    			dt.Tick += delegate
    			{
    				counter++;
    				if (counter == 6)
    				{
    					dt.Stop();
    					if (a == 4)
    						a = 0;
    					else
    						a = a + 1;
    					GoToState(a);
    				}
    			};
    			
    			dt.Interval = new TimeSpan(0, 0, 0, 1);
    			dt.Start();
    		}
    		
    		private void GoToState(int a)
    		{
    			VisualState v = vsg.States[a] as VisualState;
    			currentState = v;
    			VisualStateManager.GoToState(this, currentState.Name.ToString(), true);
    			StartTimer(a);
    		}
    
    		private void TextBlock_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    		{
    			dt.Stop();
    			TextBlock tb = sender as TextBlock;
    			int a = Convert.ToInt16(tb.Text) - 1;
    			VisualState v = vsg.States[a] as VisualState;
    			currentState = v;
    			GoToState(a);
    		}
    
    		//The following will pause the animation on MouseEnter and resume on MouseLeave.
    		private void Canvas_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
    		{
    			dt.Stop();
    		}
    
    		private void Canvas_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
    		{
    			int a = vsg.States.IndexOf(currentState);
    			StartTimer(a);
    		}
    	}
    }

    I hope that gives you some ideas.

    Uploaded to SkyDrive: SLSlideShow2_MikeyN

    ~Christine


    My Gallery - calControls

  • Wednesday, December 05, 2012 3:53 AM
     
     

    Christine, thank you so much. It's great!!

    I'm assuming that I needed to add code in order to get this working, am I correct?

    I've opened the project up and noticed you had several states, however I didn't see where they fired up. How does the transition loop?

    I'm not much into coding, I primarily work with blend 4.

    I would like to learn how to do this stuff for future reference.

    Mike

  • Wednesday, December 05, 2012 4:27 AM
     
      Has Code

    Christine, thank you so much. It's great!!

    I'm assuming that I needed to add code in order to get this working, am I correct?

    I've opened the project up and noticed you had several states, however I didn't see where they fired up. How does the transition loop?

    I'm not much into coding, I primarily work with blend 4.

    I would like to learn how to do this stuff for future reference.

    Mike

    I knew nothing about coding till I got my first copy of Blend.  Blend 2. :D  So we get to learn together.  And the moderators and community here are great with us newcomers.

    If you look in the "Projects" panel (top left usually) and you'll see all the files in the project.  Expand the "MainPage.xaml" and you'll see MainPage.xaml.cs.

    That is the code-behind file, and yes I did the loop in code-behind, specifically in the timer.  This bit here...

    private void StartTimer(int a)
    		{
    			dt = new DispatcherTimer();
    			int counter = 0;
    			
    			dt.Tick += delegate
    			{
    				counter++;
    				if (counter == 6)
    				{
    					dt.Stop();
    					if (a == 4)
    						a = 0;
    					else
    						a = a + 1;
    					GoToState(a);
    				}
    			};
    			
    			dt.Interval = new TimeSpan(0, 0, 0, 1);
    			dt.Start();
    		}

    When the timer gets to 6 seconds (you may want to change that) ... if (counter == 6)

    I designated "a" as the current state number.  The first in the list will always be index 0, second will be index 1, etc...

    So if the timer hit 6 then it looks at what state it is on...  and if (a == 4) or the last state it says to go back to the first state or state 0.  So a = 0;

    Else go to the next state … a = a + 1;

    Then I have a method which I am calling called GoToState(int a).  By plugging in "a" or the new current state number, it will jump to that state.

    .....

    Additionally the VisualStateGroup or "vsg" is the collection of states I created in the Blend UI.  State1 thru State5.  State1 = Index 0 of the list, State2 = Index 1 of the list and so-on...

    I also added MouseEnter and MouseLeave events. Mostly out of habit. I don't like a screen changing when someone is in the middle of reading it.  Just delete this part in the xaml … MouseEnter="Canvas_MouseEnter" MouseLeave="Canvas_MouseLeave" If you don't want that behavior.

    I really hope I haven't confused you at all.

    ~Christine


    My Gallery - calControls

  • Wednesday, December 05, 2012 5:07 AM
     
      Has Code

    I cleaned up the code a bit and took out parts that weren't needed.  I also added comments to explain what the methods/lines were up to...

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Threading;
    
    namespace SLSlideShow2
    {
    	public partial class MainPage : UserControl
    	{
    		VisualStateGroup vsg;  //This will be the list of states.  State1, State2, etc...
    		VisualState currentState;  //This is the current state the program is on/in.
    		DispatcherTimer dt;  //This timer I am using for the Auto Scrolling or Looping.
    		
    		public MainPage()
    		{
    			InitializeComponent();
    		}
    
    		private void UserControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
    		{
    			//This method is called when the page or UserControl loads.
    			//By calling VisualStateManager.GoToState I am setting it to the first state.
    			
    			VisualStateManager.GoToState(this, "State1", true);
    			vsg = this.VisualStateGroup;  //This is the list of states in the project.
    			currentState = vsg.States[0] as VisualState;  //Keeping track of the current state so we can scroll.
    			StartTimer(0);  //This calls timer. And sets a to 0 or the first state.
    		}		
    		
    		private void StartTimer(int a)
    		{
    			dt = new DispatcherTimer();  //This creates a new timer.
    			int counter = 0;  //starts the timer count at 0
    			
    			dt.Tick += delegate
    			{
    				counter++;  //this increases the timer by 1 every tick.
    				if (counter == 6)  //if the timer has hit 6 ticks, then do the stuff in brackets.  You may want to change the time.
    				{
    					dt.Stop();  //stops the timer.
    					if (a == 4)  //if a = 4 or the last state in the list, then we set a to 0 or the first state.
    						a = 0;
    					else
    						a = a + 1;  //otherwise we call the next state or a + 1.
    					GoToState(a);  //by plugging in the new a value and calling GoToState() it will advance.
    				}
    			};
    			
    			dt.Interval = new TimeSpan(0, 0, 0, 1);  //this is what sets your time  ... this timespan is set for seconds and one tick = 1 second.
    			dt.Start();  //this starts the timer.
    		}
    		
    		private void GoToState(int a)
    		{
    			VisualState v = vsg.States[a] as VisualState;
    			currentState = v;
    			VisualStateManager.GoToState(this, currentState.Name.ToString(), true);  //this actually changes the state
    			StartTimer(a);  //starts the timer all over again.
    		}
    
    		private void TextBlock_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    		{
    			//this method is called when you click on one of the numbers.
    			
    			dt.Stop();  //first we are stopping the timer.
    			TextBlock tb = sender as TextBlock;  //Setting tb to be which ever TextBlock was clicked.
    			int a = Convert.ToInt16(tb.Text) - 1;  //getting our "a" by converting the text to a number.
    			VisualState v = vsg.States[a] as VisualState;
    			currentState = v;
    			GoToState(a);
    		}
    
    		//The following will pause the animation on MouseEnter and resume on MouseLeave.
    		private void Canvas_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
    		{
    			dt.Stop();  //Stops the timer when the mouse enters.
    		}
    
    		private void Canvas_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
    		{
    			//the following is the only place currentState is used.  
    			int a = vsg.States.IndexOf(currentState);
    			StartTimer(a);  //Starting the timer when the mouse leaves.
    		}
    	}
    }

    Hopefully that will be easier to understand than my explanation above. :)

    http://sdrv.ms/TFRdQS

    ~Christine


    My Gallery - calControls