Estoy animando un cambio de tamaño de borde en Silverlight, sin embargo, también necesito eliminar gradualmente el margen alrededor de él (actualmente 50). La mezcla no parece generar una interpolación para el cambio de margen, simplemente salta de 50 a 0 de una vez. ¿Hay una manera de lograr esto?Animate Margin Change en Silverlight
Respuesta
El problema es que el margen es realmente del tipo "System.Windows.Thickness", que no es un objeto de dependencia, por tanto, Izquierda, Arriba, Derecha, Abajo y no son propiedades de dependencia y por lo tanto no puede ser animado usando DoubleAnimation (que permite interpolación).
Lo que se usa para animar el Margen es una Anotación de Objeto que no interpola. Es por eso que ve el margen saltar desde su ubicación original a su nueva ubicación. Como otro ejemplo común, sucede lo mismo cuando intenta animar la propiedad Visibilidad entre Visible y Derrumbado.
Tendría que hacer una animación basada en temporizador para animar el margen o implementar su propio tipo de animación para objetos de grosor.
Ben Lemmon da una solución elegante: http://blogs.msdn.com/blemmon/archive/2009/03/18/animating-margins-in-silverlight.aspx
Here is an updated version que le permite animar desde dentro XAML
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace NiceCards.Animations
{
public class ThicknessAnimationX
{
public static readonly DependencyProperty ElementProperty = DependencyProperty.RegisterAttached("Element", typeof(DependencyObject), typeof(DoubleAnimation), new PropertyMetadata(new PropertyChangedCallback(OnElementPropertyChanged)));
// The time along the animation from 0-1
public static DependencyProperty TimeProperty = DependencyProperty.RegisterAttached("Time", typeof(double), typeof(DoubleAnimation), new PropertyMetadata(OnTimeChanged));
// The object being animated
public static DependencyProperty TargetProperty = DependencyProperty.RegisterAttached("Target", typeof(DependencyObject), typeof(ThicknessAnimationX), null);
public static DependencyProperty TargetPropertyProperty = DependencyProperty.RegisterAttached("TargetProperty", typeof(DependencyProperty), typeof(DependencyObject), null);
public static readonly DependencyProperty FromProperty = DependencyProperty.RegisterAttached("From", typeof(Thickness), typeof(DoubleAnimation), null);
public static readonly DependencyProperty ToProperty = DependencyProperty.RegisterAttached("To", typeof(Thickness), typeof(DoubleAnimation), null);
public static void SetElement(DependencyObject o, DependencyObject value)
{
o.SetValue(ElementProperty, value);
}
public static DependencyObject GetElement(DependencyObject o)
{
return (DependencyObject)o.GetValue(ElementProperty);
}
private static void OnElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue != null)
{
DoubleAnimation doubleAnimation = (DoubleAnimation)d;
doubleAnimation.SetValue(TargetProperty, e.NewValue);
doubleAnimation.From = 0;
doubleAnimation.To = 1;
doubleAnimation.SetValue(TargetPropertyProperty, FrameworkElement.MarginProperty);
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(ThicknessAnimationX.Time)"));
Storyboard.SetTarget(doubleAnimation, doubleAnimation);
}
}
private static void OnTimeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
DoubleAnimation animation = (DoubleAnimation)sender;
double time = GetTime(animation);
Thickness from = (Thickness)sender.GetValue(FromProperty);
Thickness to = (Thickness)sender.GetValue(ToProperty);
DependencyProperty targetProperty = (DependencyProperty)sender.GetValue(TargetPropertyProperty);
DependencyObject target = (DependencyObject)sender.GetValue(TargetProperty);
target.SetValue(targetProperty, new Thickness((to.Left - from.Left) * time + from.Left,
(to.Top - from.Top) * time + from.Top,
(to.Right - from.Right) * time + from.Right,
(to.Bottom - from.Bottom) * time + from.Bottom));
}
public static double GetTime(DoubleAnimation animation)
{
return (double)animation.GetValue(TimeProperty);
}
public static void SetTime(DoubleAnimation animation, double value)
{
animation.SetValue(TimeProperty, value);
}
public static Thickness GetFrom(DoubleAnimation animation)
{
return (Thickness)animation.GetValue(FromProperty);
}
public static void SetFrom(DoubleAnimation animation, Thickness value)
{
animation.SetValue(FromProperty, value);
}
public static Thickness GetTo(DoubleAnimation animation)
{
return (Thickness)animation.GetValue(ToProperty);
}
public static void SetTo(DoubleAnimation animation, Thickness value)
{
animation.SetValue(ToProperty, value);
}
}
}
Y entonces usted puede hacer esto en XAML
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Positions">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.2"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Left">
<Storyboard>
<DoubleAnimation Duration="0:0:0.3" NiceCards:ThicknessAnimationX.To="0,0,0,0" NiceCards:ThicknessAnimationX.Element="{Binding ElementName=rectangle1}" Storyboard.TargetName="rectangle1" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Right">
<Storyboard>
<DoubleAnimation Duration="0:0:0.3" NiceCards:ThicknessAnimationX.To="0,200,0,0" NiceCards:ThicknessAnimationX.Element="{Binding ElementName=rectangle1}" Storyboard.TargetName="rectangle1" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle Height="100" HorizontalAlignment="Left" Margin="23,25,0,0" x:Name="rectangle1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="200" Fill="#FF1BAA00"/>
Tenga en cuenta que si no establece una propiedad Target en una doble animación en XAML, no podrá mostrar el control/página en Blend. Para solucionar esto, simplemente agregue una propiedad de destino falso (en el código anterior agregué la propiedad de opacidad que es un valor doble), y se anulará en tiempo de ejecución de todos modos
- 1. Animate Margin/Thickness
- 2. C# Silverlight Datagrid - Fila Color Change
- 3. Css margin-top vs margin-bottom
- 4. jQuery .animate() Problemas
- 5. ¿Hay alguna diferencia entre "margin: 0 auto;" y "margin: auto;"
- 6. Programmatically set textblock margin
- 7. div padding, margin?
- 8. Animate Expander en WPF
- 9. jQuery: Animate Margins to Auto?
- 10. altura Animate UITableViewCell en la selección
- 11. Rails change change sequence or order
- 12. WPF equivalent of margin-top?
- 13. margin-left: auto y margin-right: auto no funciona en la entrada
- 14. CSS margin-top no funciona en IE7
- 15. change error_message en Zend_Validate_EmailAddress
- 16. Animate cosas como en jQuery?
- 17. jquery.ui.spinner change
- 18. WPF - Animate ListBox.ScrollViewer.HorizontalOffset?
- 19. jQuery animate scrollTop
- 20. Java Animate JLabel
- 21. Android Animate Girar
- 22. .animate con una curva
- 23. jQuery animate .prepend
- 24. Jquery animate bottom problema
- 25. Animate giratoria UIImageView
- 26. Animate eliminación de anotaciones
- 27. Cómo bucle .animate JQuery
- 28. Animate PNGs with jQuery?
- 29. Animate Inserciones a ItemsControl
- 30. Animate cambio de altura de la celda en UITableView
He intentado usar esto en XAML de acuerdo con su ejemplo y recibo una secuencia de errores en SL5. Agregué una declaración 'xmlns: someName', pero parece que XAML no sabe qué es una propiedad' someName: ThicknessAnimationX'. – Shaamaan