WPF. La forma más fácil de mover la imagen a (X, Y) programáticamente?

¿Alguien sabe de una manera fácil de animar un movimiento desde la ubicación actual de una imagen a una nueva ubicación (X, Y) usando animación WPF sin XAML, 100% programáticamente? Y sin referencia a “esto” (con RegisterName, etc.).

Estoy tratando de hacer una clase de extensión para que Image haga cosas de animación en ella. Es bastante fácil cambiar las propiedades de ancho y alto a través de la animación, pero después de buscar la animación de ubicación de un objeto, de repente se vuelve más avanzado.

Como es una clase de extensión, solo tendré una referencia al objeto de imagen real y las X e YI quiero moverlo a.

public static void MoveTo(this Image targetControl, double X, double Y, double Width, double Height){ //code here ... } 

Actualizar:

Gracias. Casi trabajando. Parece que GetTop y GetLeft devuelven ‘NaN’ no establecido explícitamente. Encontré la solución alternativa en esta publicación: Canvas.GetTop () devolviendo NaN

 public static void MoveTo(this Image target, double newX, double newY) { Vector offset = VisualTreeHelper.GetOffset(target); var top = offset.Y; var left = offset.X; TranslateTransform trans = new TranslateTransform(); target.RenderTransform = trans; DoubleAnimation anim1 = new DoubleAnimation(0, newY - top, TimeSpan.FromSeconds(10)); DoubleAnimation anim2 = new DoubleAnimation(0, newX - left, TimeSpan.FromSeconds(10)); trans.BeginAnimation(TranslateTransform.YProperty, anim1); trans.BeginAnimation(TranslateTransform.XProperty, anim2); } 

Tuve que intercambiar dos de los valores (FROM) con 0. Supongo que debe ser porque en este contexto, la esquina superior izquierda de la imagen es el origen? Pero ahora funciona.

Prueba esto:

 public static void MoveTo(this Image target, double newX, double newY) { var top = Canvas.GetTop(target); var left = Canvas.GetLeft(target); TranslateTransform trans = new TranslateTransform(); target.RenderTransform = trans; DoubleAnimation anim1 = new DoubleAnimation(top, newY - top, TimeSpan.FromSeconds(10)); DoubleAnimation anim2 = new DoubleAnimation(left, newX - left, TimeSpan.FromSeconds(10)); trans.BeginAnimation(TranslateTransform.XProperty,anim1); trans.BeginAnimation(TranslateTransform.YProperty,anim2); } 

Aquí está … Cambia el tamaño y mueve un MediaElement debajo del Canvas . Solo ingrese sus parámetros:

 Storyboard story = new Storyboard(); DoubleAnimation dbWidth = new DoubleAnimation(); dbWidth.From = mediaElement1.Width; dbWidth.To = 600; dbWidth.Duration = new Duration(TimeSpan.FromSeconds(.25)); DoubleAnimation dbHeight = new DoubleAnimation(); dbHeight.From = mediaElement1.Height; dbHeight.To = 400; dbHeight.Duration = dbWidth.Duration; story.Children.Add(dbWidth); Storyboard.SetTargetName(dbWidth, mediaElement1.Name); Storyboard.SetTargetProperty(dbWidth, new PropertyPath(MediaElement.WidthProperty)); story.Children.Add(dbHeight); Storyboard.SetTargetName(dbHeight, mediaElement1.Name); Storyboard.SetTargetProperty(dbHeight, new PropertyPath(MediaElement.HeightProperty)); DoubleAnimation dbCanvasX = new DoubleAnimation(); dbCanvasX.From = 0; dbCanvasX.To = 5; dbCanvasX.Duration = new Duration(TimeSpan.FromSeconds(.25)); DoubleAnimation dbCanvasY = new DoubleAnimation(); dbCanvasY.From = 0; dbCanvasY.To = 5; dbCanvasY.Duration = dbCanvasX.Duration; story.Children.Add(dbCanvasX); Storyboard.SetTargetName(dbCanvasX, mediaElement1.Name); Storyboard.SetTargetProperty(dbCanvasX, new PropertyPath(Canvas.LeftProperty)); story.Children.Add(dbCanvasY); Storyboard.SetTargetName(dbCanvasY, mediaElement1.Name); Storyboard.SetTargetProperty(dbCanvasY, new PropertyPath(Canvas.TopProperty)); story.Begin(this); 

         

ACTUALIZAR:

En lugar de MediaElement usa esta línea:

   

Y no olvides poner el código C # en:

 private void button1_Click(object sender, RoutedEventArgs e) {} 

Puede usar MediaElement también, pero debe definir un VideoClip para ver algo;)

Este código está basado en la respuesta de @ DeanChalk.

Mueve una Image contenida dentro de un Canvas ( RFID_Token ) en diagonal desde la parte superior derecha a la inferior izquierda, posicionada centralmente sobre otra Image dentro de un Canvas ( RFID_Reader ).

         

 var StartX = Canvas.GetLeft(RFID_Token); var StartY = Canvas.GetTop(RFID_Token); var EndX = RFID_Reader.Width / 2 + Canvas.GetLeft(RFID_Reader) - StartX - (RFID_Token.Width / 2); var EndY = RFID_Reader.Height / 2 + Canvas.GetTop(RFID_Reader) - StartY - (RFID_Token.Height / 2); var AnimationX = new DoubleAnimation(0, EndX, TimeSpan.FromSeconds(1)); var AnimationY = new DoubleAnimation(0, EndY, TimeSpan.FromSeconds(1)); var Transform = new TranslateTransform(); RFID_Token_Canvas.RenderTransform = Transform; Transform.BeginAnimation(TranslateTransform.XProperty, AnimationX); Transform.BeginAnimation(TranslateTransform.YProperty, AnimationY); 

Seguí teniendo valores NaN o 0 para mis elementos nesteds, aquí hay una versión modificada de la respuesta de Danny:

  public void MoveTo(Canvas canvas, FrameworkElement target, FrameworkElement destination) { Point oldPoint = target.TransformToAncestor(canvas).Transform(new Point(0, 0)); Point newPoint = destination.TransformToAncestor(canvas).Transform(new Point(0, 0)); var EndX = destination.Width / 2 + newPoint.X - oldPoint.X - (target.Width / 2); var EndY = destination.Height / 2 + newPoint.Y - oldPoint.Y - (target.Height / 2); TranslateTransform trans = new TranslateTransform(); target.RenderTransform = trans; DoubleAnimation anim1 = new DoubleAnimation(0, EndX, TimeSpan.FromSeconds(0.3)); DoubleAnimation anim2 = new DoubleAnimation(0, EndY, TimeSpan.FromSeconds(0.3)); trans.BeginAnimation(TranslateTransform.XProperty, anim1); trans.BeginAnimation(TranslateTransform.YProperty, anim2); } 

Encuentre una solución que use las propiedades Izquierda y Superior de Lienzo para el método de extensión. Vea el siguiente código:

  public static void MoveTo(this Image target, Point newP) { Point oldP = new Point(); oldP.X = Canvas.GetLeft(target); oldP.Y = Canvas.GetTop(target); DoubleAnimation anim1 = new DoubleAnimation(oldP.X, newP.X, TimeSpan.FromSeconds(0.2)); DoubleAnimation anim2 = new DoubleAnimation(oldP.Y, newP.Y , TimeSpan.FromSeconds(0.2)); target.BeginAnimation(Canvas.LeftProperty , anim1); target.BeginAnimation(Canvas.TopProperty, anim2); }