2009-03-28 7 views
9

J'utilise DoubleAnimation pour analyser la propriété Angle d'un RotationTransform. Plusieurs fois par seconde, j'ai besoin de changer le taux de rotation en réponse à des données externes afin que la rotation accélère et/ou ralentisse (doucement) au fil du temps. Je fais actuellement cela en utilisant un DoubleAnimation qui se répète toujours de 0,0 à 360,0 avec une durée X, puis plusieurs fois par seconde:Modifier dynamiquement une animation de rotation dans WPF

  • Faire une nouvelle valeur à partir de données externes
  • Modifier le taux sur le DoubleAnimation que valeur
  • réappliquer le DoubleAnimation à la propriété angle encore

note: Je ne trouve que je devais changer le vers et à partir des propriétés de l'animation « angle actuel » et « angle actuel + 360 » - chanceux pour moi RotationTransform n'a aucun problème avec les angles > 360 degrés - pour éviter de recommencer la rotation depuis l'angle zéro.

Ma question est: Est-ce raisonnable? Cela ne semble pas être le cas. Appliquer continuellement de nouvelles DoubleAnimations à la propriété Angle sur une transformation de rotation semble faux - un peu comme si je laissais WPF animer la rotation, alors que I animais moi-même la vitesse de rotation.

Y a-t-il un meilleur moyen?

Répondre

8

Sur le storyboard, il y a un paramètre SpeedRatio qui est un multiplicateur de la durée. Vous ne pouvez pas lier cela cependant car ce n'est pas une propriété de dépendance. Pour contourner ce problème, vous pouvez utiliser la fonction SetSpeedRatio du storyboard. Notez que cela ne fonctionne que si le storyboard est démarré en code (sinon vous obtenez une erreur).

Le code ci-dessous est un exemple complet de la manière dont vous déclenchez un événement dans un objet pour affecter la vitesse d'animation d'un rectangle en rotation. Le but de la zone de texte et des liaisons de données est de mettre à jour l'objet d'arrière-plan. Le bouton est juste de sorte que la zone de texte perd le focus et met à jour l'objet.

<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> 

Ensuite, le code 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); } 
    } 
} 

Je suis sûr que vous pouvez adapter à votre utilisation.

+0

Cela serait très apprécié. – Bill

+1

Merci, je serai en mesure d'utiliser cela. C'est drôle que nous devions faire un appel de méthode (SetSpeedRatio), ce qui signifie que je ne peux pas animer le changement de rapport de vitesse avec une autre animation, tout en Xaml et tout; mais cela semble beaucoup plus correct que d'appliquer de nouvelles animations tout le temps pour obtenir l'effet. Merci. – Bill

+0

Cette réponse était très utile dans notre cas, mais il y a une différence importante qui ne l'a pas fait fonctionner. au moins avec WPF dans WinRT. La méthode SetSpeedRatio() n'a rien fait donc nous l'avons changé à la propriété SpeedRatio et cela a fait l'affaire. –

Questions connexes