How to: Interactively Control a Clock
A Clock object's ClockController property enables you to interactively start, pause, resume, seek, advance the clock to its fill period, and stop the clock. Only the root clock of a timing tree can be interactively controlled.
Note: |
---|
There are other ways to interactively control animations that don't require you to work directly with clocks: you can also use Storyboards. Storyboards are supported in both markup and code. For an example, see How to: Animate a Property by Using a Storyboard or the Animation Overview. |
In the following example, several buttons are used to interactively control an animation clock.
Example
/*
This example shows how to interactively control
a root clock.
*/
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
namespace Microsoft.Samples.Animation.TimingBehaviors
{
public class ClockControllerExample : Page
{
private AnimationClock myControllableClock;
private Button seekButton;
private TextBox seekAmountTextBox;
private ListBox timeSeekOriginListBox;
public ClockControllerExample()
{
StackPanel mainPanel = new StackPanel();
// Create a rectangle to animate.
Rectangle animatedRectangle = new Rectangle();
animatedRectangle.Width = 100;
animatedRectangle.Height = 100;
animatedRectangle.Fill = Brushes.Orange;
mainPanel.Children.Add(animatedRectangle);
// Create a DoubleAnimation to
// animate its width.
DoubleAnimation widthAnimation =
new DoubleAnimation(
100,
500,
new Duration(TimeSpan.FromSeconds(5)));
// Create a clock from the animation.
myControllableClock = widthAnimation.CreateClock();
// Apply the clock to the rectangle's Width property.
animatedRectangle.ApplyAnimationClock(
Rectangle.WidthProperty, myControllableClock);
myControllableClock.Controller.Stop();
//
// Create some buttons to control the clock.
//
// Create a button to begin the clock.
Button beginButton = new Button();
beginButton.Content = "Begin";
beginButton.Click +=
new RoutedEventHandler(beginButton_Clicked);
mainPanel.Children.Add(beginButton);
// Create a button to pause the clock.
Button pauseButton = new Button();
pauseButton.Content = "Pause";
pauseButton.Click +=
new RoutedEventHandler(pauseButton_Clicked);
mainPanel.Children.Add(pauseButton);
// Create a button to resume the clock.
Button resumeButton = new Button();
resumeButton.Content = "Resume";
resumeButton.Click +=
new RoutedEventHandler(resumeButton_Clicked);
mainPanel.Children.Add(resumeButton);
// Create a button to advance the clock to
// its fill period.
Button skipToFillButton = new Button();
skipToFillButton.Content = "Skip to Fill";
skipToFillButton.Click +=
new RoutedEventHandler(skipToFillButton_Clicked);
mainPanel.Children.Add(skipToFillButton);
// Create a button to stop the clock.
Button stopButton = new Button();
stopButton.Content = "Stop";
stopButton.Click +=
new RoutedEventHandler(stopButton_Clicked);
mainPanel.Children.Add(stopButton);
//
// Create some controls the enable the user to
// seek the clock.
//
StackPanel seekDetailsPanel = new StackPanel();
seekDetailsPanel.Margin = new Thickness(0,20,0,20);
seekDetailsPanel.Orientation = Orientation.Horizontal;
Label seekAmountLabel = new Label();
seekAmountLabel.Content = "Seek amount:";
seekDetailsPanel.Children.Add(seekAmountLabel);
// Create a text box so that the user can
// specify the amount by which to seek.
seekAmountTextBox = new TextBox();
seekAmountTextBox.Text = "0:0:1";
seekAmountTextBox.VerticalAlignment = VerticalAlignment.Top;
seekAmountTextBox.TextChanged +=
new TextChangedEventHandler(seekAmountTextBox_TextChanged);
seekDetailsPanel.Children.Add(seekAmountTextBox);
Label timeSeekOriginLabel = new Label();
timeSeekOriginLabel.Content = "Seek Origin:";
seekDetailsPanel.Children.Add(timeSeekOriginLabel);
// Create a ListBox so the user can
// select whether the seek time is relative
// to the clock's BeginTime or Duration.
timeSeekOriginListBox = new ListBox();
timeSeekOriginListBox.Items.Add("BeginTime");
timeSeekOriginListBox.Items.Add("Duration");
timeSeekOriginListBox.Padding = new Thickness(5);
timeSeekOriginListBox.SelectedIndex = 0;
seekDetailsPanel.Children.Add(timeSeekOriginListBox);
// Create a button to seek the clock.
seekButton = new Button();
seekButton.Content = "Seek";
seekButton.Click += new RoutedEventHandler(seekButton_Clicked);
seekDetailsPanel.Children.Add(seekButton);
mainPanel.Children.Add(seekDetailsPanel);
this.Content = mainPanel;
}
// Starts the clock.
private void beginButton_Clicked(object sender, RoutedEventArgs e)
{
myControllableClock.Controller.Begin();
}
// Pauses the clock.
private void pauseButton_Clicked(object sender, RoutedEventArgs e)
{
myControllableClock.Controller.Pause();
}
// Resumes the clock.
private void resumeButton_Clicked(object sender, RoutedEventArgs e)
{
myControllableClock.Controller.Resume();
}
// Adances the clock to its fill period.
private void skipToFillButton_Clicked(object sender, RoutedEventArgs e)
{
myControllableClock.Controller.SkipToFill();
}
// Stops the clock.
private void stopButton_Clicked(object sender, RoutedEventArgs e)
{
myControllableClock.Controller.Stop();
}
// Seeks the clock.
private void seekButton_Clicked(object sender, RoutedEventArgs e)
{
try {
// Obtain the seek amount from the seekAmountTextBox TextBox.
TimeSpan seekAmount = TimeSpan.Parse(seekAmountTextBox.Text);
// Determine the seek origin by reading the selected value
// from the timeSeekOriginListBox ListBox.
TimeSeekOrigin selectedOrigin =
(TimeSeekOrigin)Enum.Parse(typeof(TimeSeekOrigin),
(string)timeSeekOriginListBox.SelectedItem);
// Seek to the specified location.
myControllableClock.Controller.Seek(seekAmount, selectedOrigin);
}catch(FormatException formatEx)
{
MessageBox.Show(seekAmountTextBox.Text
+ " is not a valid TimeSpan. Please enter another value.");
// Disable the seek button until the user enters another value.
seekButton.IsEnabled = false;
}
}
// Verifies that seekAmountTextBox has text content.
// If there is no text, disable the seek button.
private void seekAmountTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox theTextBox = (TextBox)e.Source;
if (theTextBox.Text == null || theTextBox.Text.Length < 1)
seekButton.IsEnabled = false;
else
seekButton.IsEnabled = true;
}
}
}
See Also
Tasks
How to: Animate a Property by Using a Storyboard