How do I move a FrameworkElement across a Canvas without stuttering in WPF?

352 Views Asked by At

I want to move a FrameworkElement, e.g. a TextBlock, across a Canvas from left to right whenever a button is pressed and held. If you just click the button, the FrameworkElement should be moved 1 pixel.

This is possible to achieve with the code below but I get a lot of stuttering while the FrameworkElement is moving.

The XAML part:

<Canvas>
    <TextBlock x:Name="MoveTextBlock" Text="Move Me" Canvas.Left="0"/>
    <RepeatButton Content="Move" Width="90" Height="30" Canvas.Bottom="20" 
Canvas.Left="20" Click="RepeatButton_Click" Delay="150" Interval="2"/>
</Canvas>

In code-behind:

private void RepeatButton_Click(object sender, RoutedEventArgs e)
{
    Canvas.SetLeft(MoveTextBlock, Canvas.GetLeft(MoveTextBlock) + 1);
}

What I have tried (but not necessarily in the right way):

  • Using CacheMode
  • Adjusting Delay and Interval for the RepeatButton
  • Using a BackgroundWorker
  • Using a Storyboard

The Storyboard almost did the job but I then got another problem with the animation slowing down after a while, which is not what I want either.

Is it possible to completely avoid stutter?

EDIT:

I gave the Storyboard another attempt. I solved the problem I had with the animation slowing down (all animations got added to the same Storyboard), but now the stuttering happens in this solution too:

private void RepeatButton_Click(object sender, RoutedEventArgs e)
{
    DoubleAnimation doubleAnimation = new DoubleAnimation();
    double left = Canvas.GetLeft(MoveTextBlock);
    doubleAnimation.From = left;
    doubleAnimation.To = left + 1;
    doubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(0));

    Storyboard.SetTargetName(doubleAnimation, MoveTextBlock.Name);
    Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath(Canvas.LeftProperty));

    Storyboard moveTextBlockStoryboard = new Storyboard();
    moveTextBlockStoryboard.Children.Add(doubleAnimation);

    moveTextBlockStoryboard.Begin(MoveTextBlock);
}
0

There are 0 best solutions below