Click here to Skip to main content
15,879,239 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I've been trying to finger this out for a few days. I simply want to animate the position of a control in a form. I tried animating the margin (using a ThicknessAnimation), but that didn't work, so now I'm trying to animate a TranslateTransform, and it simply doesn't move the window. What am I not doing?

public enum MoveVector { X, Y, XY };

private void MoveTo(FrameworkElement control, MoveVector vector, double x, double y)
{
    try
    {
        Storyboard sb = new Storyboard();
        sb.AutoReverse = false;

        System.Windows.Point point = control.TransformToAncestor((FrameworkElement)control.Parent).Transform(new System.Windows.Point(0, 0));

        DoubleAnimation animY = null; 
        DoubleAnimation animX = null; 

        if (vector == MoveVector.Y || vector == MoveVector.XY)
        {
            animY = new DoubleAnimation(point.Y, y, new Duration(new TimeSpan(5000)), FillBehavior.Stop);
            animY.By = 1d;
            Timeline.SetDesiredFrameRate(animY, 30);
            Storyboard.SetTarget(animY, control);
            Storyboard.SetTargetProperty(animY, new PropertyPath(TranslateTransform.YProperty));
            sb.Children.Add(animY);
        }
        if (vector == MoveVector.X || vector == MoveVector.XY)
        {
            animX = new DoubleAnimation(point.X, x, new Duration(new TimeSpan(5000)), FillBehavior.Stop);
            animX.By = 1d;
            Timeline.SetDesiredFrameRate(animX, 30);
            Storyboard.SetTarget(animX, control);
            Storyboard.SetTargetProperty(animX, new PropertyPath(TranslateTransform.XProperty));
            sb.Children.Add(animX);
        }
        sb.Begin();
    }
    catch (Exception ex)
    {
        if (ex != null) {}
    }
}
Posted
Updated 19-Oct-13 1:13am
v3
Comments
Sergey Alexandrovich Kryukov 17-Oct-13 17:13pm    
Just a preliminary advice: to checkup how some property would affect the view, modify this property in some event, like in response click on some UIElement. I though animation of the thickness should work, but you might have missed something; as to the translate, it depends on the container. Of course it works on canvas, but hardly on panel which has automatic layout: docked, stacked panel, grid, etc. You probably remember that if you modify, say, property Left of some docked control, it won't move anyway. See the point? Note that on Canvas you would animate attached property of a dependency element (child, in this case) which is designed to move the child element...
—SA
Kenneth Haugland 17-Oct-13 18:16pm    
I made it work on a stackpanel, if you try the last code in the link below. So I dont think it should be an issue.
Sergey Alexandrovich Kryukov 17-Oct-13 18:18pm    
Well, what exactly did you? It depends...
—SA
Kenneth Haugland 17-Oct-13 18:25pm    
My issue was that the New PropertyPath("Data.EndPoint") wanted a String, and not a Property in that sence.
#realJSOP 22-Oct-13 6:25am    
It's not on a docked panel. Setting the X/Y properties on the transform in XML puts the control in the desired location, so animating those properties should work fine.

1 solution

It seems that the documentation requires the storyboard to be registered as a Resource in order to function properly, that means applying a name to it, and adding it as a Resource etc. This is quite well explained in MSDN[^], but I didnt know about it either.

Implementation taken from a question on StackOverFlow seem to give you the answer on how to proceed:
C#
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace WpfAnnimationTransform
{

    public partial class MainWindow : Window
    {

        Canvas panel;
        public MainWindow()
        {
            InitializeComponent();
            MouseDown += DoDynamicAnimation;

            Content = panel = new Canvas();
        }

        void DoDynamicAnimation(object sender, MouseButtonEventArgs args)
        {
            for (int i = 0; i < 12; ++i)
            {
                var e = new Button { Width = 16, Height = 16 }; //new Ellipse { Width = 16, Height = 16, Fill = SystemColors.HighlightBrush };
                Canvas.SetLeft(e, Mouse.GetPosition(this).X);
                Canvas.SetTop(e, Mouse.GetPosition(this).Y);

                var tg = new TransformGroup();
                var translation = new TranslateTransform(30, 0);
                var translationName = "myTranslation" + translation.GetHashCode();
                RegisterName(translationName, translation);
                tg.Children.Add(translation);
                tg.Children.Add(new RotateTransform(i * 30));
                e.RenderTransform = tg;

                panel.Children.Add(e);

                var anim = new DoubleAnimation(3, 150, new Duration(new TimeSpan(0, 0, 0, 2, 0)))
                {
                    EasingFunction = new PowerEase { EasingMode = EasingMode.EaseOut }
                };

                var s = new Storyboard();
                Storyboard.SetTargetName(s, translationName);
                Storyboard.SetTargetProperty(s, new PropertyPath(TranslateTransform.YProperty));
                var storyboardName = "s" + s.GetHashCode();
                Resources.Add(storyboardName, s);

                s.Children.Add(anim);

                s.Completed +=
                    (sndr, evtArgs) =>
                    {
                        panel.Children.Remove(e);
                        Resources.Remove(storyboardName);
                        UnregisterName(translationName);
                    };
                s.Begin();
            }
        }
    }
}

The code is taken from this[^]. A little too many buttons perhaps ;)
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900