2009-03-28 32 views
9

Estoy usando una doble animación para anamiar la propiedad Ángulo de una Transformación de rotación. Varias veces por segundo, necesito cambiar la velocidad de rotación en respuesta a los datos externos para que la rotación se acelere o desacelere (sin problemas) con el tiempo. Actualmente estoy haciendo esto usando un DoubleAnimation que se repite siempre de 0.0 a 360,0 con una duración X, luego varias veces por segundo:Cambie dinámicamente una animación de rotación en WPF

  • Coge un nuevo valor a partir de datos externos
  • modificar la velocidad en la DoubleAnimation a ese valor
  • volver a aplicar el DoubleAnimation a la propiedad ángulo de nuevo

Nota: me pareció que tenía que cambiar el a y desde las propiedades de la animación "ángulo actual" y "ángulo actual + 360" - Por suerte para mí RotationTransform no tiene problemas con los ángulos > 360 grados - para evitar que comience nuevamente la rotación desde el ángulo cero.

Mi pregunta es: ¿es esto razonable? No parece así. La aplicación continua de nuevas DoubleAnimations a la propiedad Angle en una transformación de rotación parece incorrecta, algo así como dejar que WPF anime la rotación, mientras que I estoy animando la velocidad de rotación.

¿Hay una manera mejor?

Respuesta

8

En el guión gráfico hay una configuración de SpeedRatio que es un multiplicador de la duración. No se puede vincular a esto sin embargo, ya que no es una propiedad de dependencia.

Para evitar esto, puede utilizar la función SetSpeedRatio en el guión gráfico. Tenga en cuenta que esto solo funciona si el storyboard se inicia en código (de lo contrario, se obtiene un error).

El siguiente código es un ejemplo completo de cómo se elevaría el evento en un objeto para afectar la velocidad de la animación de un rectángulo giratorio. El propósito de los enlaces textbox y data es actualizar el objeto de fondo. El botón es solo para que el cuadro de texto pierda el foco y actualice el objeto.

<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <StackPanel> 
     <Rectangle Margin="50" Width="50" Height="50" Fill="Red" x:Name="rc"> 
     <Rectangle.RenderTransform> 
      <RotateTransform x:Name="TransRotate" 
          CenterX="25" CenterY="25" Angle="0" /> 
     </Rectangle.RenderTransform> 
     <Rectangle.Resources> 
      <Storyboard x:Key="spin"> 
      <DoubleAnimation x:Name="da" 
          Storyboard.TargetName="TransRotate" 
          Storyboard.TargetProperty="Angle" 
          By="360" 
          Duration="0:0:10" 
          AutoReverse="False" 
          RepeatBehavior="Forever" /> 
      </Storyboard> 
     </Rectangle.Resources> 
     </Rectangle> 
     <TextBox Text="{Binding Speed}" /> 
     <Button>Update Speed</Button> 
    </StackPanel> 
</Window> 

A continuación, el código C#

{ 
    public Window1() 
    { 
     InitializeComponent(); 

     //create new object 
     BackgroundObject bo = new BackgroundObject(); 

     //binding only needed for the text box to change speed value 
     this.DataContext = bo; 

     //Hook up event 
     bo.SpeedChanged += bo_SpeedChanged; 

     //Needed to prevent an error 
     Storyboard sb = (Storyboard)rc.FindResource("spin"); 
     sb.Begin(); 
    } 

    //Change Speed 
    public void bo_SpeedChanged( object sender, int newSpeed) 
    { 
     Storyboard sb = (Storyboard)rc.FindResource("spin"); 
     sb.SetSpeedRatio(newSpeed); 
    } 
} 

public delegate void SpeedChangedEventHandler(object sender, int newSpeed); 

public class BackgroundObject 
{ 
    public BackgroundObject() 
    { 
     _speed = 10; 
    } 

    public event SpeedChangedEventHandler SpeedChanged; 

    private int _speed; 
    public int Speed 
    { 
     get { return _speed; } 
     set { _speed = value; SpeedChanged(this,value); } 
    } 
} 

Estoy seguro de que puede adaptarse a su uso.

+0

Eso sería muy apreciado. – Bill

+1

Gracias, podré usar eso. Es curioso que tengamos que hacer una llamada a un método (SetSpeedRatio), lo que significa que no puedo animar el cambio de relación de velocidad con otra animación, todo en Xaml y todo; pero esto parece mucho más correcto que aplicar nuevas animaciones todo el tiempo para obtener el efecto. Gracias. – Bill

+0

Esta respuesta fue muy útil en nuestro caso, pero hay una diferencia importante que no lo hizo funcionar. al menos con WPF en WinRT. El método SetSpeedRatio() no hizo nada, así que lo cambiamos a la propiedad SpeedRatio y eso funcionó. –

Cuestiones relacionadas