Pregunta

Estoy Animación de una frontera de cambiar el tamaño de Silverlight sin embargo también necesito para eliminar gradualmente el margen de alrededor de él (actualmente 50). Mezcla no parece generar una interpolación para el cambio de margen - que sólo salta de 50 a 0 en una sola vez. ¿Hay una manera de lograr esto?

¿Fue útil?

Solución

El problema es que un 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 por interpolación).

Lo que se utiliza para animar el margen es una ObjectAnimation que no hace interpolación. Es por esto que se ve el salto margen de su ubicación original a su nueva ubicación. Como otro ejemplo común, lo mismo sucede cuando se intenta animar la propiedad de visibilidad entre visible y se derrumbó.

Usted ya sea que tenga que hacer la animación basada temporizador con el fin de animar margen o implementar su propio tipo de Animación de objetos de espesor.

Otros consejos

Aquí es una versión actualizada 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 se establece una propiedad de destino a un DoubleAnimation en XAML, usted no será capaz de mostrar el control / la página en Blend. Para solucionar este problema, basta con añadir una propiedad de destino falsa (en el código anterior añadí la propiedad de opacidad que es un valor doble), Y será anulado en tiempo de ejecución de todos modos

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top