views:

634

answers:

2

In my WPF application, I have a Canvas object that contains some UserControl objects.

I wish to animate the UserControl objects within the Canvas using DoubleAnimation so that they go from the right of the Canvas to the left of the Canvas. This is how I have done it so far (by passing the UserControl objects into the function):

    private void Animate(FrameworkElement e)
    {
        DoubleAnimation ani = new DoubleAnimation()
        {
            From = _container.ActualWidth,
            To = 0.0,
            Duration = new Duration(new TimeSpan(0, 0, 10),
            TargetElement = e
        };

        TranslateTransform trans = new TranslateTransform();
        e.RenderTransform = trans;

        trans.BeginAnimation(TranslateTransform.XProperty, ani, HandoffBehavior.Compose);
    }

However, this doesn't allow me to pause the animation, so I have considered using a Storyboard instead to do this, but I'm not sure how to implement this. This has been my attempt so far:

    private void Animate(FrameworkElement e)
    {
        DoubleAnimation ani = new DoubleAnimation()
        {
            From = _container.ActualWidth,
            To = 0.0,
            Duration = new Duration(new TimeSpan(0, 0, 10),
            TargetElement = e
        };

        Storyboard stb = new Storyboard();
        Storyboard.SetTarget(ani, e);
        Storyboard.SetTargetProperty(ani, "Left");
        stb.Children.Add(ani);
        stb.Begin();
    }

Of course, this fails as UserControl doesn't have a Left property. How can I achieve what I'm after?

Thanks.

+1  A: 

Neo,

I think I have solved your problem. Here is what I've done:

I created a grid, with rows within it. In the first row, i put a stack panel to align my start, pause, resume buttons. In the second row, i placed a rectangle (my object that will animate). I then wired up some triggers for the start, pause, and resume buttons to start, pause, and resume the animation. Here is the code that I used:

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
     <Grid.Triggers>

      <EventTrigger SourceName="StartBtn" RoutedEvent="Button.Click">
       <EventTrigger.Actions>
        <BeginStoryboard x:Name="MyStoryboard">
         <Storyboard >
          <DoubleAnimation Storyboard.TargetName="MovingRect" Storyboard.TargetProperty="RenderTransform.(TranslateTransform.X)" From="0" To="250"  AutoReverse="True" RepeatBehavior="Forever"/>
         </Storyboard>
        </BeginStoryboard>
       </EventTrigger.Actions>
      </EventTrigger>
      <EventTrigger SourceName="StopBtn" RoutedEvent="Button.Click" >
       <PauseStoryboard BeginStoryboardName="MyStoryboard" />
      </EventTrigger>
      <EventTrigger SourceName="ResumeBtn" RoutedEvent="Button.Click" >
       <ResumeStoryboard BeginStoryboardName="MyStoryboard" />
      </EventTrigger>
     </Grid.Triggers>
     <Grid.RowDefinitions>
      <RowDefinition />
      <RowDefinition />
     </Grid.RowDefinitions>
     <StackPanel Orientation="Horizontal" Grid.Row="0">
      <Button  x:Name="StartBtn" Content="Start" Width="100" />
      <Button  x:Name="StopBtn" Content="Pause" Width="100" />
      <Button  x:Name="ResumeBtn" Content="Resume" Width="100" />
     </StackPanel>
     <Rectangle Name="MovingRect" Fill="Red" Width="50" Height="25" Grid.Row="2" HorizontalAlignment="Left">
      <Rectangle.RenderTransform>
       <TranslateTransform X="0" Y="0" />
      </Rectangle.RenderTransform>
     </Rectangle>
    </Grid>
</Window>

Here is my resulting output:
Output

I've added the code to my Google Code project for your download. I've also zipped up the source code and it is available at the following address:

http://stackoverflow-answers-by-scott.googlecode.com/files/1789718.zip

Also, here is a very good reference to WPF animations:

http://dotnetslackers.com/articles/wpf/IntroductionToWPFAnimations.aspx

I hope this helps,

Thanks!

Scott
Unfortunately, I need to do this programmatically (in the C# code-behind), and simply wish to modify my working Animate function to attach the DoubleAnimation object to a Storyboard object. Your code seems fine for XAML to achieve Start/Pause/Resume functionality, but I have a much simpler requirement - to attach a DoubleAnimation object to a Storyboard object and specify a property (in Storyboard.SetTargetProperty) to cause the target object to move across the Canvas from right to left. Is this possible?
Neo
A: 

Just to keep this Question updated, I eventually resolved the problem. The DoubleAnimation and Storyboard were being created and Storyboard.Begin() called on in a DispatcherTimer Tick event handler.

The trick was to dispatch the call to a delegate that called Storyboard.Begin().

Neo