WPF France

  • Augmenter la taille
  • Taille par défaut
  • Diminuer la taille

Créer, démarrer et contrôler une animation depuis le code sur n'importe quel objet

Envoyer Imprimer PDF
Note des utilisateurs: / 0
MauvaisTrès bien 
Il est parfois nécessaire d'animer un objet particulier (je devrais plutôt dire une valeur particulière) en WPF et pour cela il y a les animations. Cependant pour pouvoir les utiliser sur un objet, nous sommes confrontés à certains pré-requis :
  • La propriété à animer doit être une DependencyProperty,
  • Cela entraine par la même que l'objet animé doit être un DependencyObject,
  • L'objet doit implémenté l'interface IAnimatable afin d'être en mesure de lancer l'animation.

Nous allons voir comment contourner ce problème pour créer, lancer et contrôler une animation sur tout type d'objet avec WPF depuis le code !


Le processus est consistué de plusieurs étapes :

  1. Créer l'animation,
  2. Créer un storyboard (le contenu de l'animation),
  3. Définir les bonnes valeurs pour les propriétés TargetName et TargetProperty.
Le tout directement dans le code !

La solution que j'utilise

Premièrement nous crééons un objet dérivant de FrameworkElement. Pourquoi ? Parceque cela a le double avantage d'être un DependencyObject et d'implémenter IAnimatable( FrameworkElement hérite de UIElement qui implémente IAnimatable). De plus il possède un NameScope, chose qui est nécessaire comme nous le verrons plus tard.

Je vous présente donc mon objet "poupée" :
public class Puppet: FrameworkElement {    }
Ensuite, nous ajoutons une DependencyProperty qui sera la valeur animée. Dans notre cas, on utilise une valeur de type Point mais il faut choisir le type qui vous convient. On ajouter de même un Storyboard à cet objet.
public class Puppet: FrameworkElement { public static DependencyProperty ContactMovementProperty = 
    DependencyProperty.Register("ContactMovement", typeof(Point), typeof(Puppet)); 

 public Point ContactMovement   { 
   get { return (Point)GetValue(SatelliteNavigator.ContactMovementProperty); }       
   set { SetValue(SatelliteNavigator.ContactMovementProperty, value); }
  }  

  private Storyboard stboard = new Storyboard();
}
Alors, nous allons créer et lancer l'animation directement depuis le constructeur de l'objet (le code est commenté en dessous) :
public class()

{
  //Maybe it was running before (if not set in the constructor)
  //stboard.Stop();
 
  double xFinal = 36;
  double yFinal = 36;
  PointAnimation animation = new PointAnimation();
 
  animation.From = ContactMovement;
  animation.To = new Point(xFinal , yFinal );
  animation.Duration = TimeSpan.FromMilliseconds(e.Velocity.Length*7 / deceleration);
  animation.AccelerationRatio = 0f;
  animation.DecelerationRatio = 0.4f;
  String puppetName= "puppet"+Guid.NewGuid().ToString();
 
  NameScope nams = new NameScope();
  NameScope.SetNameScope(this, nams);
  this.RegisterName(puppetName, this);
 
  Storyboard.SetTargetName(animation, puppetName);
  Storyboard.SetTargetProperty(animation, new PropertyPath(Puppet.ContactMovementProperty));
 
  stboard.Children.Add(animation);
  stboard.Begin(this); 
}

Qu'est ce qui est fait ? Tout d'abord on instancie un objet Animation avec des valeurs aléatoires. Ensuite, un NameScope est créé et assigné à notre objet. Ceci est nécessaire, car comme celui-ci n'est pas instancié par le runtime, aucun ne lui est attribué. Ce NameScope sera utilisé par l'animation pour retrouver l'objet à animer.

On fournit donc le nom de notre poupée à l'animation en l'assignant à la propriété TargetName via la méthode static (StoryBoard.SetTargetName).

Pour finir, on vide les enfants présent dans le StoryBoard(qui n'était peut être pas vide) et nous démarrons l'animation en fournissant l'objet à animer (soi-même : this).

Ensutie, il est facile de contrôler les animations via les méthodes du Storyboard :
stboard.Stop();

Conclusion

Comme vous avez pu le lire, ce n'est pas la façon préconisée par Microsoft qui préfère laisser ce travail aux designers via XAML mais cela reste tout de même possible !

(Article traduit de l'anglais depuis : http://blog.lexique-du-net.com )

Commentaires (0)
Mise à jour le Mardi, 23 Mars 2010 10:17  

Partagez