locked
Resume a Storyboard after Interruption or State Change RRS feed

  • Question

  • Silverlight 3 and Expression Blend 3 - I posted a similiar question earlier but it was probably too vague.

    I have included the XAML and Code for a test project. Storyboard 1 runs when the project begins and there are GoToStateActions on Buttons 1 and 2. On Mouse action they run Storyboard4 and 6 respectively which time out and the image goes to zero opacity. In Silverlight when you interrupt a Storyboard it "stops", in this case Storyboard1 is interrupted. I want Storyboard1 to "resume" when either of the other Storyboards end so I assume I need a "Storyboard1.resume();"  statement somewhere, I'm just not sure where to put it. XAML and C# are new to me, so sorry if this is a simplistic coding question, but I would appreciate your help. Here is the XAML and Code. It all works as is, just need to add the resume to re-start or resume Storyboard1.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    
    namespace Silverlight_Trigger
    {
      public partial class MainPage : UserControl
      {
        public MainPage()
        {
          InitializeComponent();
          Storyboard1.Begin();
          
        }
    
    
    XAML:
    
    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"
      mc:Ignorable="d"
      xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:ic="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions" x:Class="Silverlight_Trigger.MainPage"
      d:DesignHeight="350" d:DesignWidth="700">
    
    	<UserControl.Resources>
    		<Storyboard x:Name="Storyboard1" RepeatBehavior="Forever">
    			<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image2" Storyboard.TargetProperty="(UIElement.Opacity)">
    				<DiscreteDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
    				<DiscreteDoubleKeyFrame KeyTime="00:00:07" Value="1"/>
    				<DiscreteDoubleKeyFrame KeyTime="00:00:14" Value="0"/>
    			</DoubleAnimationUsingKeyFrames>
    			<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image1" Storyboard.TargetProperty="(UIElement.Opacity)">
    				<DiscreteDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
    				<DiscreteDoubleKeyFrame KeyTime="00:00:07" Value="0"/>
    				<DiscreteDoubleKeyFrame KeyTime="00:00:14" Value="0"/>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    	</UserControl.Resources>
    
      <Canvas x:Name="LayoutRoot" Background="White">
      	<VisualStateManager.VisualStateGroups>
      		<VisualStateGroup x:Name="View1">
      			<VisualState x:Name="Storyboard4">
      				<Storyboard>
      					<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image1" Storyboard.TargetProperty="(UIElement.Opacity)">
      						<EasingDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
      						<DiscreteDoubleKeyFrame KeyTime="00:00:03" Value="0"/>
      					</DoubleAnimationUsingKeyFrames>
      				</Storyboard>
      			</VisualState>
      		</VisualStateGroup>
      		<VisualStateGroup x:Name="View2">
      			<VisualStateGroup.Transitions>
      			</VisualStateGroup.Transitions>
      			<VisualState x:Name="Storyboard6">
      				<Storyboard>
      					<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image2" Storyboard.TargetProperty="(UIElement.Opacity)">
      						<DiscreteDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
      						<DiscreteDoubleKeyFrame KeyTime="00:00:03" Value="0"/>
      					</DoubleAnimationUsingKeyFrames>
      				</Storyboard>
      			</VisualState>
      		</VisualStateGroup>
      	</VisualStateManager.VisualStateGroups>
      	<Image x:Name="Button1" Height="60" Width="40" Canvas.Left="64" Canvas.Top="80" Source="Chrysanthemum 40x60.jpg" Stretch="Fill" MouseLeftButtonDown="OnMouseButtonDown">
      		<i:Interaction.Triggers>
      			<i:EventTrigger EventName="MouseLeftButtonDown">
      				<ic:GoToStateAction StateName="Storyboard4"/>
      			</i:EventTrigger>
      		</i:Interaction.Triggers>
      	</Image>
      	<Image x:Name="image2" Height="270" Width="500" Canvas.Left="172" Canvas.Top="24" Source="Tulips 500x270.jpg" Stretch="Fill"/>
      	<Image x:Name="Button2" Height="60" Width="40" Canvas.Left="64" Canvas.Top="188" Source="Tulips 40x60.jpg" Stretch="Fill" MouseLeftButtonUp="OnMouseButtonUp">
      		<i:Interaction.Triggers>
      			<i:EventTrigger EventName="MouseLeftButtonDown">
      				<ic:GoToStateAction StateName="Storyboard6"/>
      			</i:EventTrigger>
      		</i:Interaction.Triggers>
      	</Image>
      	<Image x:Name="image1" Height="270" Width="500" Opacity="0" Canvas.Left="172" Canvas.Top="24" Source="Chrysanthemum 500x270.jpg" Stretch="Fill"/>
    
      </Canvas>
    </UserControl>
    
    Wednesday, May 5, 2010 4:58 PM

Answers

  • I put together a little example of how you could do this, please note the code is raw, and probably ugly, because I just threw it together in a few free minutes this morning :)

    It uses a usercontrol to display images, and a behavior to trigger the popup images, I believe this behaves the way you specified it. Mine uses the images from win 7 sample pictures folder, added to my project in an /Images folder.

     

    ImageDisplay.xaml

    <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"
    	mc:Ignorable="d"
    	x:Class="SilverlightApplication44.ImageDisplay"
    	d:DesignWidth="640" d:DesignHeight="480">
    <UserControl.Resources>
    		<Storyboard x:Name="HideImageStoryboard">
    			<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="MainImage" Storyboard.TargetProperty="(UIElement.Opacity)">
    				<EasingDoubleKeyFrame KeyTime="00:00:00" Value="1">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CubicEase EasingMode="EaseInOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0"/>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    		<Storyboard x:Name="ShowImageStoryboard">
    			<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="MainImage" Storyboard.TargetProperty="(UIElement.Opacity)">
    				<EasingDoubleKeyFrame KeyTime="00:00:00" Value="0">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CubicEase EasingMode="EaseInOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CubicEase EasingMode="EaseInOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    		<Storyboard x:Name="HidePopupImageStoryboard">
    			<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="PopupImage" Storyboard.TargetProperty="(UIElement.Opacity)">
    				<EasingDoubleKeyFrame KeyTime="00:00:00" Value="1">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CubicEase EasingMode="EaseInOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0"/>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    		<Storyboard x:Name="ShowPopupImageStoryboard">
    			<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="PopupImage" Storyboard.TargetProperty="(UIElement.Opacity)">
    				<EasingDoubleKeyFrame KeyTime="00:00:00" Value="0">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CubicEase EasingMode="EaseInOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CubicEase EasingMode="EaseInOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    	</UserControl.Resources>
    
    	<Grid x:Name="LayoutRoot" Opacity="1">
    		<Image x:Name="MainImage" Margin="0" Opacity="0" Source="{Binding CurrentImage, Mode=OneWay}"/>
    		<Image x:Name="PopupImage" Margin="0" Opacity="0" Source="{Binding CurrentPopupImage, Mode=OneWay}"/>
    	</Grid>
    </UserControl>

    ImageDisplay.xaml.cs

    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Threading;
    
    namespace SilverlightApplication44
    {
    	public partial class ImageDisplay : UserControl, System.ComponentModel.INotifyPropertyChanged
    	{
    		private System.Windows.Media.ImageSource currentImage = null;
    
    		public System.Windows.Media.ImageSource CurrentImage
    		{
    			get
    			{
    				return this.currentImage;
    			}
    
    			set
    			{
    				if (this.currentImage != value)
    				{
    					this.currentImage = value;
    					this.OnPropertyChanged("CurrentImage");
    				}
    			}
    		}
    
    		private System.Windows.Media.ImageSource currentPopupImage = null;
    
    		public System.Windows.Media.ImageSource CurrentPopupImage
    		{
    			get
    			{
    				return this.currentPopupImage;
    			}
    
    			set
    			{
    				if (this.currentPopupImage != value)
    				{
    					this.currentPopupImage = value;
    					this.OnPropertyChanged("CurrentPopupImage");
    				}
    			}
    		}
    
    		public List<System.Windows.Media.ImageSource> Images { get; set; }
    		private int currentImageIndex = 0;
    		private DispatcherTimer timer;
    		private DispatcherTimer popupTimer;
    
    		public ImageDisplay()
    		{
    			// Required to initialize variables
    			InitializeComponent();
    			this.LayoutRoot.DataContext = this;
    
    			this.Images = new List<System.Windows.Media.ImageSource>();
    
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Chrysanthemum.jpg", UriKind.Relative)));
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Desert.jpg", UriKind.Relative)));
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Hydrangeas.jpg", UriKind.Relative)));
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Jellyfish.jpg", UriKind.Relative)));
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Koala.jpg", UriKind.Relative)));
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Lighthouse.jpg", UriKind.Relative)));
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Penguins.jpg", UriKind.Relative)));
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Tulips.jpg", UriKind.Relative)));
    			this.CurrentImage = this.Images[0];
    			ShowImage();
    			timer = new DispatcherTimer();
    			timer.Interval = TimeSpan.FromSeconds(3);
    			timer.Tick += new EventHandler(t_Tick);
    			timer.Start();
    
    			popupTimer = new DispatcherTimer();
    			popupTimer.Interval = TimeSpan.FromSeconds(3);
    			popupTimer.Tick += new EventHandler(popupTimer_Tick);
    
    			this.HideImageStoryboard.Completed += new EventHandler(HideImageStoryboard_Completed);
    			this.ShowImageStoryboard.Completed += new EventHandler(ShowImageStoryboard_Completed);
    			this.ShowPopupImageStoryboard.Completed += new EventHandler(ShowPopupImageStoryboard_Completed);
    			this.HidePopupImageStoryboard.Completed += new EventHandler(HidePopupImageStoryboard_Completed);
    		}
    
    		public void ShowSpecificImage(int index)
    		{
    			this.CurrentPopupImage = this.Images[index];
    			timer.Stop();
    			this.ShowPopupImageStoryboard.Begin();
    		}
    
    		void popupTimer_Tick(object sender, EventArgs e)
    		{
    			this.popupTimer.Stop();
    			this.HidePopupImageStoryboard.Begin();
    		}
    
    		void HidePopupImageStoryboard_Completed(object sender, EventArgs e)
    		{
    			timer.Start();
    		}
    
    		void ShowPopupImageStoryboard_Completed(object sender, EventArgs e)
    		{
    			this.popupTimer.Start();
    		}
    
    		void ShowImageStoryboard_Completed(object sender, EventArgs e)
    		{
    			timer.Start();
    		}
    
    		void HideImageStoryboard_Completed(object sender, EventArgs e)
    		{
    			ChangeImage();
    		}
    
    		void t_Tick(object sender, EventArgs e)
    		{
    			timer.Stop();
    			HideImage();
    		}
    
    		private void ChangeImage()
    		{
    			currentImageIndex = (currentImageIndex + 1) % this.Images.Count;
    			this.CurrentImage = this.Images[currentImageIndex];
    			ShowImage();
    		}
    
    
    		public void ShowImage()
    		{
    			this.ShowImageStoryboard.Begin();
    		}
    
    		public void HideImage()
    		{
    			this.HideImageStoryboard.Begin();
    
    		}
    
    		protected virtual void OnPropertyChanged(string propertyName)
    		{
    			if (this.PropertyChanged != null)
    			{
    				this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
    			}
    		}
    
    		public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    	}
    }

    MainPage.xaml

    <UserControl
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	xmlns:local="clr-namespace:SilverlightApplication44" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    	x:Class="SilverlightApplication44.MainPage"
    	Width="640" Height="480">
    
    	<Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding Source={StaticResource SampleDataSource}}">
    		<VisualStateManager.VisualStateGroups>
    			<VisualStateGroup x:Name="VisualStateGroup">
    				<VisualStateGroup.Transitions>
    					<VisualTransition GeneratedDuration="00:00:01"/>
    				</VisualStateGroup.Transitions>
    				<VisualState x:Name="VisualState"/>
    				<VisualState x:Name="VisualState1"/>
    			</VisualStateGroup>
    		</VisualStateManager.VisualStateGroups>
    		<Border Margin="150,8,8,8" BorderBrush="Red" BorderThickness="2" CornerRadius="2">
    			<local:ImageDisplay x:Name="imageDisplay">
    				<i:Interaction.Triggers>
    					<i:EventTrigger EventName="Click" SourceName="button">
    						<local:LoadImageAction/>
    					</i:EventTrigger>
    					<i:EventTrigger EventName="MouseLeftButtonDown" SourceName="image">
    						<local:LoadImageAction ImageIndex="1"/>
    					</i:EventTrigger>
    				</i:Interaction.Triggers>
    			</local:ImageDisplay>
    		</Border>
    		<Button x:Name="button" Height="46" HorizontalAlignment="Left" Margin="23,8,0,0" VerticalAlignment="Top" Width="83">
    			<Image Height="39" Width="52" Source="Images/Chrysanthemum.jpg" Stretch="Fill"/>
    		</Button>
    		<Image x:Name="image" Height="77" HorizontalAlignment="Left" Margin="8,82,0,0" VerticalAlignment="Top" Width="103" Source="Images/Desert.jpg" Stretch="Fill"/>
    	</Grid>
    </UserControl>

    LoadImageAction.cs

    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;
    
    namespace SilverlightApplication44
    {
    	//
    	// If you want your Action to target elements other than its parent, extend your class
    	// from TargetedTriggerAction instead of from TriggerAction
    	//
    	public class LoadImageAction : TriggerAction<ImageDisplay>
    	{
    		public static readonly DependencyProperty ImageIndexProperty = DependencyProperty.Register("ImageIndex", typeof(int), typeof(LoadImageAction), new PropertyMetadata(0));
    
    		public int ImageIndex
    		{
    			get { return (int)GetValue(ImageIndexProperty); }
    			set { SetValue(ImageIndexProperty, value); }
    		}
    
    		public LoadImageAction()
    		{
    		}
    
    		protected override void Invoke(object o)
    		{
    			this.AssociatedObject.ShowSpecificImage(this.ImageIndex);
    		}
    	}
    }

    • Proposed as answer by Chuck HaysModerator Thursday, May 6, 2010 4:29 PM
    • Marked as answer by IBISDev Thursday, May 6, 2010 5:57 PM
    Thursday, May 6, 2010 4:28 PM
    Moderator

All replies

  • I'm not entirely clear on what you are trying to accomplish, but this *might* do what you want.  However, since this is new to you, it might be more helpful if you describe what you are trying to accomplish, and we might be able to come up with an easier way to do it. Just provide as much detail as you can :)

    public partial class MainPage : UserControl
    	{
    		public MainPage()
    		{
    			// Required to initialize variables
    			InitializeComponent();
    			
    			Storyboard4.Storyboard.Completed += new System.EventHandler(Storyboard_Completed);
    			Storyboard6.Storyboard.Completed += new System.EventHandler(Storyboard_Completed);
    			
    			Storyboard1.Begin();
    		}
    
    		private void Storyboard_Completed(object sender, System.EventArgs e)
    		{
    			Storyboard1.Resume();
    		}
    	}

    Wednesday, May 5, 2010 8:30 PM
    Moderator
  • Thanks for the reply,

    The Silverlight will be on a home page and will have multiple images that will be displayed as Storyboard1 runs. I have all the images in the same location on the artboard and I change their opacity as the Storyboard runs. I have Buttons along side the images that when clicked would start another storyboard (Storyboard4 in the example) and display the image associated with the Button. When Storyboard4 ends, I change the image to zero opacityand I want Storyboard1 to resume. This would be the same for multiple images and buttons. Everytime a button is clicked the associated image would be shown until its storyboard ends and then Storyboard1 resumes. The images associated with each button are the same ones that play in Storyboard 1. I'm open to suggestions :-)

     

    Wednesday, May 5, 2010 8:51 PM
  • So to be sure I understand, you want a slideshow with buttons that can pull up specific images temporarily? So say you have images A, B,C,D,E, the normal loops displays then in order, but if you click a button for image C, it should show C for some time period, and then go back to wherever it was in the loop?  So if it was displaying A at the time, it should show C for a time period, then go back to A/B?

     

    Wednesday, May 5, 2010 9:06 PM
    Moderator
  • Yes, that is it. Right now I have all the images in one storyboard so they run continuously.
    Wednesday, May 5, 2010 9:12 PM
  • Sorry, one storyboard for what you called the normal loops.
    Wednesday, May 5, 2010 9:14 PM
  • I put together a little example of how you could do this, please note the code is raw, and probably ugly, because I just threw it together in a few free minutes this morning :)

    It uses a usercontrol to display images, and a behavior to trigger the popup images, I believe this behaves the way you specified it. Mine uses the images from win 7 sample pictures folder, added to my project in an /Images folder.

     

    ImageDisplay.xaml

    <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"
    	mc:Ignorable="d"
    	x:Class="SilverlightApplication44.ImageDisplay"
    	d:DesignWidth="640" d:DesignHeight="480">
    <UserControl.Resources>
    		<Storyboard x:Name="HideImageStoryboard">
    			<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="MainImage" Storyboard.TargetProperty="(UIElement.Opacity)">
    				<EasingDoubleKeyFrame KeyTime="00:00:00" Value="1">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CubicEase EasingMode="EaseInOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0"/>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    		<Storyboard x:Name="ShowImageStoryboard">
    			<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="MainImage" Storyboard.TargetProperty="(UIElement.Opacity)">
    				<EasingDoubleKeyFrame KeyTime="00:00:00" Value="0">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CubicEase EasingMode="EaseInOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CubicEase EasingMode="EaseInOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    		<Storyboard x:Name="HidePopupImageStoryboard">
    			<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="PopupImage" Storyboard.TargetProperty="(UIElement.Opacity)">
    				<EasingDoubleKeyFrame KeyTime="00:00:00" Value="1">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CubicEase EasingMode="EaseInOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0"/>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    		<Storyboard x:Name="ShowPopupImageStoryboard">
    			<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="PopupImage" Storyboard.TargetProperty="(UIElement.Opacity)">
    				<EasingDoubleKeyFrame KeyTime="00:00:00" Value="0">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CubicEase EasingMode="EaseInOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    				<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1">
    					<EasingDoubleKeyFrame.EasingFunction>
    						<CubicEase EasingMode="EaseInOut"/>
    					</EasingDoubleKeyFrame.EasingFunction>
    				</EasingDoubleKeyFrame>
    			</DoubleAnimationUsingKeyFrames>
    		</Storyboard>
    	</UserControl.Resources>
    
    	<Grid x:Name="LayoutRoot" Opacity="1">
    		<Image x:Name="MainImage" Margin="0" Opacity="0" Source="{Binding CurrentImage, Mode=OneWay}"/>
    		<Image x:Name="PopupImage" Margin="0" Opacity="0" Source="{Binding CurrentPopupImage, Mode=OneWay}"/>
    	</Grid>
    </UserControl>

    ImageDisplay.xaml.cs

    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Threading;
    
    namespace SilverlightApplication44
    {
    	public partial class ImageDisplay : UserControl, System.ComponentModel.INotifyPropertyChanged
    	{
    		private System.Windows.Media.ImageSource currentImage = null;
    
    		public System.Windows.Media.ImageSource CurrentImage
    		{
    			get
    			{
    				return this.currentImage;
    			}
    
    			set
    			{
    				if (this.currentImage != value)
    				{
    					this.currentImage = value;
    					this.OnPropertyChanged("CurrentImage");
    				}
    			}
    		}
    
    		private System.Windows.Media.ImageSource currentPopupImage = null;
    
    		public System.Windows.Media.ImageSource CurrentPopupImage
    		{
    			get
    			{
    				return this.currentPopupImage;
    			}
    
    			set
    			{
    				if (this.currentPopupImage != value)
    				{
    					this.currentPopupImage = value;
    					this.OnPropertyChanged("CurrentPopupImage");
    				}
    			}
    		}
    
    		public List<System.Windows.Media.ImageSource> Images { get; set; }
    		private int currentImageIndex = 0;
    		private DispatcherTimer timer;
    		private DispatcherTimer popupTimer;
    
    		public ImageDisplay()
    		{
    			// Required to initialize variables
    			InitializeComponent();
    			this.LayoutRoot.DataContext = this;
    
    			this.Images = new List<System.Windows.Media.ImageSource>();
    
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Chrysanthemum.jpg", UriKind.Relative)));
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Desert.jpg", UriKind.Relative)));
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Hydrangeas.jpg", UriKind.Relative)));
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Jellyfish.jpg", UriKind.Relative)));
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Koala.jpg", UriKind.Relative)));
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Lighthouse.jpg", UriKind.Relative)));
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Penguins.jpg", UriKind.Relative)));
    			this.Images.Add(new System.Windows.Media.Imaging.BitmapImage(new Uri("/SilverlightApplication44;component/Images/Tulips.jpg", UriKind.Relative)));
    			this.CurrentImage = this.Images[0];
    			ShowImage();
    			timer = new DispatcherTimer();
    			timer.Interval = TimeSpan.FromSeconds(3);
    			timer.Tick += new EventHandler(t_Tick);
    			timer.Start();
    
    			popupTimer = new DispatcherTimer();
    			popupTimer.Interval = TimeSpan.FromSeconds(3);
    			popupTimer.Tick += new EventHandler(popupTimer_Tick);
    
    			this.HideImageStoryboard.Completed += new EventHandler(HideImageStoryboard_Completed);
    			this.ShowImageStoryboard.Completed += new EventHandler(ShowImageStoryboard_Completed);
    			this.ShowPopupImageStoryboard.Completed += new EventHandler(ShowPopupImageStoryboard_Completed);
    			this.HidePopupImageStoryboard.Completed += new EventHandler(HidePopupImageStoryboard_Completed);
    		}
    
    		public void ShowSpecificImage(int index)
    		{
    			this.CurrentPopupImage = this.Images[index];
    			timer.Stop();
    			this.ShowPopupImageStoryboard.Begin();
    		}
    
    		void popupTimer_Tick(object sender, EventArgs e)
    		{
    			this.popupTimer.Stop();
    			this.HidePopupImageStoryboard.Begin();
    		}
    
    		void HidePopupImageStoryboard_Completed(object sender, EventArgs e)
    		{
    			timer.Start();
    		}
    
    		void ShowPopupImageStoryboard_Completed(object sender, EventArgs e)
    		{
    			this.popupTimer.Start();
    		}
    
    		void ShowImageStoryboard_Completed(object sender, EventArgs e)
    		{
    			timer.Start();
    		}
    
    		void HideImageStoryboard_Completed(object sender, EventArgs e)
    		{
    			ChangeImage();
    		}
    
    		void t_Tick(object sender, EventArgs e)
    		{
    			timer.Stop();
    			HideImage();
    		}
    
    		private void ChangeImage()
    		{
    			currentImageIndex = (currentImageIndex + 1) % this.Images.Count;
    			this.CurrentImage = this.Images[currentImageIndex];
    			ShowImage();
    		}
    
    
    		public void ShowImage()
    		{
    			this.ShowImageStoryboard.Begin();
    		}
    
    		public void HideImage()
    		{
    			this.HideImageStoryboard.Begin();
    
    		}
    
    		protected virtual void OnPropertyChanged(string propertyName)
    		{
    			if (this.PropertyChanged != null)
    			{
    				this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
    			}
    		}
    
    		public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    	}
    }

    MainPage.xaml

    <UserControl
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	xmlns:local="clr-namespace:SilverlightApplication44" xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    	x:Class="SilverlightApplication44.MainPage"
    	Width="640" Height="480">
    
    	<Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding Source={StaticResource SampleDataSource}}">
    		<VisualStateManager.VisualStateGroups>
    			<VisualStateGroup x:Name="VisualStateGroup">
    				<VisualStateGroup.Transitions>
    					<VisualTransition GeneratedDuration="00:00:01"/>
    				</VisualStateGroup.Transitions>
    				<VisualState x:Name="VisualState"/>
    				<VisualState x:Name="VisualState1"/>
    			</VisualStateGroup>
    		</VisualStateManager.VisualStateGroups>
    		<Border Margin="150,8,8,8" BorderBrush="Red" BorderThickness="2" CornerRadius="2">
    			<local:ImageDisplay x:Name="imageDisplay">
    				<i:Interaction.Triggers>
    					<i:EventTrigger EventName="Click" SourceName="button">
    						<local:LoadImageAction/>
    					</i:EventTrigger>
    					<i:EventTrigger EventName="MouseLeftButtonDown" SourceName="image">
    						<local:LoadImageAction ImageIndex="1"/>
    					</i:EventTrigger>
    				</i:Interaction.Triggers>
    			</local:ImageDisplay>
    		</Border>
    		<Button x:Name="button" Height="46" HorizontalAlignment="Left" Margin="23,8,0,0" VerticalAlignment="Top" Width="83">
    			<Image Height="39" Width="52" Source="Images/Chrysanthemum.jpg" Stretch="Fill"/>
    		</Button>
    		<Image x:Name="image" Height="77" HorizontalAlignment="Left" Margin="8,82,0,0" VerticalAlignment="Top" Width="103" Source="Images/Desert.jpg" Stretch="Fill"/>
    	</Grid>
    </UserControl>

    LoadImageAction.cs

    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;
    
    namespace SilverlightApplication44
    {
    	//
    	// If you want your Action to target elements other than its parent, extend your class
    	// from TargetedTriggerAction instead of from TriggerAction
    	//
    	public class LoadImageAction : TriggerAction<ImageDisplay>
    	{
    		public static readonly DependencyProperty ImageIndexProperty = DependencyProperty.Register("ImageIndex", typeof(int), typeof(LoadImageAction), new PropertyMetadata(0));
    
    		public int ImageIndex
    		{
    			get { return (int)GetValue(ImageIndexProperty); }
    			set { SetValue(ImageIndexProperty, value); }
    		}
    
    		public LoadImageAction()
    		{
    		}
    
    		protected override void Invoke(object o)
    		{
    			this.AssociatedObject.ShowSpecificImage(this.ImageIndex);
    		}
    	}
    }

    • Proposed as answer by Chuck HaysModerator Thursday, May 6, 2010 4:29 PM
    • Marked as answer by IBISDev Thursday, May 6, 2010 5:57 PM
    Thursday, May 6, 2010 4:28 PM
    Moderator
  • Thanks a ton Chuck! I will load this and hopefully be able to learn from it. I appreciate you taking the time. I have been through the Expression Blend Help topics endlessly and looked at every video I could find. I did see a few hints when I "Binged" the issue. I will mark this as answered and vote as helpful. Is there a very helpful option?

     

    Thanks again,

    Bob Blasingame

    Thursday, May 6, 2010 5:57 PM