Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Cette rubrique montre comment utiliser des Storyboard objets pour organiser et appliquer des animations. Il décrit comment manipuler Storyboard des objets de manière interactive et décrit la syntaxe de ciblage des propriétés indirectes.
Conditions préalables
Pour comprendre cette rubrique, vous devez être familiarisé avec les différents types d’animations et leurs fonctionnalités de base. Pour une présentation de l’animation, consultez la vue d’ensemble de l’animation. Vous devez également savoir comment utiliser les propriétés jointes. Pour plus d’informations sur les propriétés jointes, consultez la vue d’ensemble des propriétés jointes.
Qu'est-ce qu'un storyboard
Les animations ne sont pas le seul type utile de chronologie. D’autres classes de chronologie sont fournies pour vous aider à organiser des ensembles de chronologies et à appliquer des chronologies aux propriétés. Les chronologies de conteneur dérivent de la TimelineGroup classe, et incluent ParallelTimeline et Storyboard.
Storyboard est un type de chronologie conteneur qui fournit des informations de ciblage pour les chronologies qu’il contient. Un Storyboard peut contenir n'importe quel type d'élément Timeline, y compris d'autres lignes de temps et animations de conteneur. Storyboard les objets vous permettent de combiner des chronologies qui affectent une variété d’objets et de propriétés dans une arborescence de chronologie unique, ce qui facilite l’organisation et le contrôle des comportements de minutage complexes. Par exemple, supposons que vous souhaitiez un bouton qui effectue ces trois opérations.
Augmentez et modifiez la couleur lorsque l’utilisateur sélectionne le bouton.
Rétrécissez puis reprenez sa taille d'origine lorsqu'on clique dessus.
Réduisez et passez à 50 % d’opacité lorsqu’il devient désactivé.
Dans ce cas, vous avez plusieurs ensembles d'animations qui s'appliquent au même objet, et vous souhaitez les jouer à des moments différents, en fonction de l'état du bouton. Storyboard les objets vous permettent d’organiser les animations et de les appliquer dans des groupes à un ou plusieurs objets.
Où pouvez-vous utiliser un storyboard ?
Un Storyboard peut être utilisé pour animer les propriétés de dépendance des classes animatables (pour plus d’informations sur ce qui rend une classe animatable, consultez la vue d’ensemble de l’animation). Toutefois, étant donné que le storyboarding est une fonctionnalité au niveau de l’infrastructure, l’objet doit appartenir à l’un des NameScope, FrameworkElement ou FrameworkContentElement.
Par exemple, vous pouvez utiliser une Storyboard commande pour effectuer les opérations suivantes :
Animer un SolidColorBrush (élément non-framework) qui peint l’arrière-plan d’un bouton (type de FrameworkElement),
Animer un SolidColorBrush (élément non-framework) qui peint le remplissage d’un GeometryDrawing (élément non-framework) affiché à l’aide d’un Image (FrameworkElement).
Dans le code, animez un SolidColorBrush déclaré dans une classe qui contient également un FrameworkElement, si le SolidColorBrush a enregistré son nom avec ce FrameworkElement.
Toutefois, vous n’avez pas pu utiliser un Storyboard pour animer un SolidColorBrush qui n’a pas inscrit son nom auprès d’un FrameworkElement ou FrameworkContentElement, ou qui n’a pas été utilisé pour définir une propriété d’un FrameworkElement ou FrameworkContentElement.
Comment appliquer des animations avec un storyboard
Pour utiliser un Storyboard pour organiser et appliquer des animations, vous ajoutez les animations en tant que sous-chronologies du Storyboard. La Storyboard classe fournit les propriétés Storyboard.TargetName jointes et Storyboard.TargetProperty. Vous définissez ces propriétés sur une animation pour spécifier son objet cible et sa propriété.
Pour appliquer des animations à leurs cibles, vous commencez par Storyboard utiliser une action de déclenchement ou une méthode. En XAML, vous utilisez un BeginStoryboard objet avec un EventTrigger, Triggerou DataTrigger. Dans le code, vous pouvez également utiliser la Begin méthode.
Le tableau suivant présente les différents endroits où chaque Storyboard technique de début est prise en charge : par instance, style, modèle de contrôle et modèle de données. « Par instance » fait référence à la technique d’application d’une animation ou d’un storyboard directement aux instances d’un objet, plutôt que dans un style, un modèle de contrôle ou un modèle de données.
On commence le storyboard en utilisant… | Par instance | Style | Modèle de contrôle | Modèle de données | Exemple : |
---|---|---|---|---|---|
BeginStoryboard et un EventTrigger | Oui | Oui | Oui | Oui | Animer une propriété à l’aide d’un storyboard |
BeginStoryboard et une propriété Trigger | Non | Oui | Oui | Oui | Déclencher une animation lorsqu’une valeur de propriété change |
BeginStoryboard et une propriété MultiTrigger | Non | Oui | Oui | Oui | Exemple de classe MultiTrigger |
BeginStoryboard et un DataTrigger | Non | Oui | Oui | Oui | Guide pratique pour déclencher une animation lorsque les données changent |
BeginStoryboard et un MultiDataTrigger | Non | Oui | Oui | Oui | Exemple de classe MultiDataTrigger |
méthode Begin | Oui | Non | Non | Non | Animer une propriété à l’aide d’un storyboard |
L’exemple suivant utilise un Storyboard pour animer le Width d'un élément Rectangle et le Color d'un SolidColorBrush utilisé pour peindre cet Rectangle.
<!-- This example shows how to animate with a storyboard.-->
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Microsoft.Samples.Animation.StoryboardsExample"
WindowTitle="Storyboards Example">
<StackPanel Margin="20">
<Rectangle Name="MyRectangle"
Width="100"
Height="100">
<Rectangle.Fill>
<SolidColorBrush x:Name="MySolidColorBrush" Color="Blue" />
</Rectangle.Fill>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="Width"
From="100" To="200" Duration="0:0:1" />
<ColorAnimation
Storyboard.TargetName="MySolidColorBrush"
Storyboard.TargetProperty="Color"
From="Blue" To="Red" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</StackPanel>
</Page>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Data;
using System.Windows.Shapes;
using System.Windows.Input;
namespace Microsoft.Samples.Animation
{
public class StoryboardsExample : Page
{
public StoryboardsExample()
{
this.WindowTitle = "Storyboards Example";
StackPanel myStackPanel = new StackPanel();
myStackPanel.Margin = new Thickness(20);
Rectangle myRectangle = new Rectangle();
myRectangle.Name = "MyRectangle";
// Create a name scope for the page.
NameScope.SetNameScope(this, new NameScope());
this.RegisterName(myRectangle.Name, myRectangle);
myRectangle.Width = 100;
myRectangle.Height = 100;
SolidColorBrush mySolidColorBrush = new SolidColorBrush(Colors.Blue);
this.RegisterName("MySolidColorBrush", mySolidColorBrush);
myRectangle.Fill = mySolidColorBrush;
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 100;
myDoubleAnimation.To = 200;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
Storyboard.SetTargetProperty(myDoubleAnimation,
new PropertyPath(Rectangle.WidthProperty));
ColorAnimation myColorAnimation = new ColorAnimation();
myColorAnimation.From = Colors.Blue;
myColorAnimation.To = Colors.Red;
myColorAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(myColorAnimation, "MySolidColorBrush");
Storyboard.SetTargetProperty(myColorAnimation,
new PropertyPath(SolidColorBrush.ColorProperty));
Storyboard myStoryboard = new Storyboard();
myStoryboard.Children.Add(myDoubleAnimation);
myStoryboard.Children.Add(myColorAnimation);
myRectangle.MouseEnter += delegate(object sender, MouseEventArgs e)
{
myStoryboard.Begin(this);
};
myStackPanel.Children.Add(myRectangle);
this.Content = myStackPanel;
}
}
}
** Les sections suivantes décrivent plus en détail les propriétés jointes TargetName et les propriétés jointes TargetProperty.
Ciblage des éléments constitutifs du framework, des éléments de contenu du framework et des objets gelables
La section précédente a mentionné que, pour qu’une animation trouve sa cible, elle doit connaître le nom de la cible et la propriété à animer. Il est simple de spécifier la propriété à animer : il suffit de définir TargetProperty
avec le nom de la propriété à animer. Vous spécifiez le nom de l'objet dont la propriété que vous souhaitez animer en définissant la propriété Storyboard.TargetName dans l'animation.
Avertissement
Bien que vous puissiez utiliser la propriété Target
pour établir une liaison directe à un objet en guise d’alternative à TargetName
, elle n’est pas sérialisable. Il n’est pas garanti que l’objet Target
puisse être correctement référencé en XAML.
Pour que la TargetName propriété fonctionne, l’objet ciblé doit avoir un nom. L’affectation d’un nom à un FrameworkElement ou à un FrameworkContentElement en XAML est différente de l’affectation d’un nom à un Freezable objet.
Les éléments d’infrastructure sont ces classes qui héritent de la FrameworkElement classe. Exemples d’éléments de framework : Window, DockPanel, Buttonet Rectangle. Essentiellement, toutes les fenêtres, panneaux et contrôles sont des éléments. Les éléments de contenu du framework sont ces classes qui héritent de la FrameworkContentElement classe. Exemples d’éléments de contenu de framework incluent FlowDocument et Paragraph. Si vous ne savez pas si un type est un élément d’infrastructure ou un élément de contenu d’infrastructure, vérifiez s’il a une propriété Name. Si c’est le cas, il s’agit probablement d’un élément de framework ou d’un élément de contenu d’infrastructure. Pour être sûr, vérifiez la section Hiérarchie d’héritage de sa page de type.
Pour activer le ciblage d’un élément de framework ou d’un élément de contenu d’infrastructure en XAML, vous définissez sa Name propriété. Dans le code, vous devez également utiliser la RegisterName méthode pour inscrire le nom de l’élément auprès de l’élément pour lequel vous avez créé un NameScope.
L’exemple suivant, extrait de l’exemple précédent, affecte le nom MyRectangle
a Rectangle, un type de FrameworkElement.
<Rectangle Name="MyRectangle"
Width="100"
Height="100">
Rectangle myRectangle = new Rectangle();
myRectangle.Name = "MyRectangle";
// Create a name scope for the page.
NameScope.SetNameScope(this, new NameScope());
this.RegisterName(myRectangle.Name, myRectangle);
Une fois qu’il a un nom, vous pouvez animer une propriété de cet élément.
<DoubleAnimation
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="Width"
From="100" To="200" Duration="0:0:1" />
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
Storyboard.SetTargetProperty(myDoubleAnimation,
new PropertyPath(Rectangle.WidthProperty));
Les types Freezable sont les classes qui héritent de la classe Freezable. Exemples de Freezable, SolidColorBrush, RotateTransform et GradientStop.
Pour activer le ciblage d’une Freezable animation en XAML, vous utilisez la directive x :Name pour lui attribuer un nom. Dans le code, vous utilisez la RegisterName méthode pour inscrire son nom auprès de l’élément pour lequel vous avez créé un NameScope.
L’exemple suivant affecte un nom à un Freezable objet.
<SolidColorBrush x:Name="MySolidColorBrush" Color="Blue" />
SolidColorBrush mySolidColorBrush = new SolidColorBrush(Colors.Blue);
this.RegisterName("MySolidColorBrush", mySolidColorBrush);
L’objet peut ensuite être ciblé par une animation.
<ColorAnimation
Storyboard.TargetName="MySolidColorBrush"
Storyboard.TargetProperty="Color"
From="Blue" To="Red" Duration="0:0:1" />
Storyboard.SetTargetName(myColorAnimation, "MySolidColorBrush");
Storyboard.SetTargetProperty(myColorAnimation,
new PropertyPath(SolidColorBrush.ColorProperty));
Storyboard les objets utilisent des étendues de nom pour résoudre la TargetName propriété. Pour plus d’informations sur les scopes de noms WPF, consultez WPF XAML Namescopes. Si la TargetName propriété est omise, l’animation cible l’élément sur lequel il est défini, ou, dans le cas des styles, l’élément de style.
Parfois, un nom ne peut pas être affecté à un Freezable objet. Par exemple, si une Freezable ressource est déclarée comme ressource ou utilisée pour définir une valeur de propriété dans un style, elle ne peut pas être nommée. Comme il n’a pas de nom, il ne peut pas être ciblé directement, mais il peut être ciblé indirectement. Les sections suivantes décrivent comment utiliser le ciblage indirect.
Ciblage indirect
Il est parfois impossible de cibler directement Freezable par une animation, par exemple lorsque Freezable est déclaré en tant que ressource ou utilisé pour définir une propriété dans un style. Dans ces cas, même si vous ne pouvez pas le cibler directement, vous pouvez toujours animer l’objet Freezable . Au lieu de définir la TargetName propriété avec le nom du Freezable, vous lui donnez le nom de l’élément auquel le Freezable « appartient ». Par exemple, un SolidColorBrush élément de rectangle utilisé pour définir l’élément Fill rectangle appartient à ce rectangle. Pour animer le pinceau, vous devez définir l'animation TargetProperty avec une chaîne de propriétés qui commence par la propriété de l'élément framework ou de l'élément de contenu framework utilisé Freezable pour la définir et se termine par la propriété Freezable à animer.
<ColorAnimation
Storyboard.TargetName="Rectangle01"
Storyboard.TargetProperty="Fill.Color"
From="Blue" To="AliceBlue" Duration="0:0:1" />
DependencyProperty[] propertyChain =
new DependencyProperty[]
{Rectangle.FillProperty, SolidColorBrush.ColorProperty};
string thePath = "(0).(1)";
PropertyPath myPropertyPath = new PropertyPath(thePath, propertyChain);
Storyboard.SetTargetProperty(myColorAnimation, myPropertyPath);
Notez que, si le Freezable est figé, un clone sera créé et ce clone sera animé. Lorsque cela se produit, la propriété de l’objet HasAnimatedProperties d’origine continue de retourner false
, car l’objet d’origine n’est pas réellement animé. Pour plus d’informations sur le clonage, consultez la vue d’ensemble des objets freezables.
Notez également que, lors de l’utilisation du ciblage de propriété indirecte, il est possible de cibler des objets qui n’existent pas. Par exemple, vous pourriez supposer que la propriété Background d'un bouton particulier a été configurée avec un SolidColorBrush et essayer d'animer sa Couleur, alors qu'en réalité un LinearGradientBrush a été utilisé pour définir le Fond du bouton. Dans ces cas, aucune exception n’est levée ; l’animation n’a pas d’effet visible, car LinearGradientBrush ne réagit pas aux modifications de la propriété Color.
Les sections suivantes décrivent plus en détail la syntaxe de ciblage des propriétés indirectes.
Ciblage indirect d’une propriété d’un Freezable en XAML
Pour cibler une propriété d’un freezable en XAML, utilisez la syntaxe suivante.
Syntaxe de propriété |
---|
ElementPropertyName. FreezablePropertyName |
Où
ElementPropertyName est la propriété de l’élément FrameworkElement, que l’Freezable est utilisé pour définir.
FreezablePropertyName est la propriété de Freezable à animer.
Le code suivant montre comment animer le Color d'un SolidColorBrush utilisé pour définir le Fill d'un rectangle.
<Rectangle
Name="Rectangle01"
Height="100"
Width="100"
Fill="{StaticResource MySolidColorBrushResource}">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetName="Rectangle01"
Storyboard.TargetProperty="Fill.Color"
From="Blue" To="AliceBlue" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Parfois, vous devez cibler un freezable contenu dans une collection ou un tableau.
Pour cibler un freezable contenu dans une collection, vous utilisez la syntaxe de chemin d’accès suivante.
Syntaxe du chemin |
---|
ElementPropertyName.Children[ CollectionIndex]. FreezablePropertyName |
Où CollectionIndex est l’index de l’objet dans son tableau ou sa collection.
Par exemple, supposons qu’un rectangle a une TransformGroup ressource appliquée à sa RenderTransform propriété et que vous souhaitez animer l’une des transformations qu’il contient.
<TransformGroup x:Key="MyTransformGroupResource"
x:Shared="False">
<ScaleTransform />
<RotateTransform />
</TransformGroup>
Le code suivant montre comment animer la Angle propriété de l’exemple RotateTransform précédent.
<Rectangle
Name="Rectangle02"
Height="100"
Width="100"
Fill="Blue"
RenderTransform="{StaticResource MyTransformGroupResource}">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="Rectangle02"
Storyboard.TargetProperty="RenderTransform.Children[1].Angle"
From="0" To="360" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Ciblage indirect d’une propriété d’un Freezable dans le code
Dans le code, vous créez un PropertyPath objet. Lorsque vous créez le PropertyPath, vous spécifiez un Path et PathParameters.
Pour créer PathParameters, vous devez créer un tableau de type DependencyProperty qui inclut une liste de champs identifiant les propriétés de dépendance. Le premier champ d’identificateur est destiné à la propriété du FrameworkElement ou du FrameworkContentElement que le Freezable est utilisé pour configurer. Le champ d’identificateur suivant représente la propriété de Freezable à cibler. Considérez-le comme une chaîne de propriétés qui connecte le Freezable à l'objet FrameworkElement.
Voici un exemple de chaîne de propriétés de dépendance qui cible le Color d’un SolidColorBrush utilisé pour définir le Fill d’un élément rectangle.
DependencyProperty[] propertyChain =
new DependencyProperty[]
{Rectangle.FillProperty, SolidColorBrush.ColorProperty};
Vous devez également spécifier un Path. Un Path est un String qui indique au Path comment interpréter son PathParameters. Elle utilise la syntaxe suivante.
Syntaxe du chemin d’accès aux propriétés |
---|
(
OwnerPropertyArrayIndex).( FreezablePropertyArrayIndex) |
Où
OwnerPropertyArrayIndex est l’index du DependencyProperty tableau qui contient l’identificateur de la propriété de l’objet FrameworkElement que Freezable est utilisé pour définir, et
FreezablePropertyArrayIndex est l’index du DependencyProperty tableau qui contient l’identificateur de propriété à cibler.
L’exemple suivant montre le Path qui accompagnerait le PathParameters défini dans l’exemple précédent.
DependencyProperty[] propertyChain =
new DependencyProperty[]
{Rectangle.FillProperty, SolidColorBrush.ColorProperty};
string thePath = "(0).(1)";
L'exemple suivant combine le code des exemples précédents pour animer le Color d'un SolidColorBrush, utilisé pour définir le Fill d'un élément rectangle.
// Create a name scope for the page.
NameScope.SetNameScope(this, new NameScope());
Rectangle rectangle01 = new Rectangle();
rectangle01.Name = "Rectangle01";
this.RegisterName(rectangle01.Name, rectangle01);
rectangle01.Width = 100;
rectangle01.Height = 100;
rectangle01.Fill =
(SolidColorBrush)this.Resources["MySolidColorBrushResource"];
ColorAnimation myColorAnimation = new ColorAnimation();
myColorAnimation.From = Colors.Blue;
myColorAnimation.To = Colors.AliceBlue;
myColorAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(myColorAnimation, rectangle01.Name);
DependencyProperty[] propertyChain =
new DependencyProperty[]
{Rectangle.FillProperty, SolidColorBrush.ColorProperty};
string thePath = "(0).(1)";
PropertyPath myPropertyPath = new PropertyPath(thePath, propertyChain);
Storyboard.SetTargetProperty(myColorAnimation, myPropertyPath);
Storyboard myStoryboard = new Storyboard();
myStoryboard.Children.Add(myColorAnimation);
BeginStoryboard myBeginStoryboard = new BeginStoryboard();
myBeginStoryboard.Storyboard = myStoryboard;
EventTrigger myMouseEnterTrigger = new EventTrigger();
myMouseEnterTrigger.RoutedEvent = Rectangle.MouseEnterEvent;
myMouseEnterTrigger.Actions.Add(myBeginStoryboard);
rectangle01.Triggers.Add(myMouseEnterTrigger);
Parfois, vous devez cibler un freezable contenu dans une collection ou un tableau. Par exemple, supposons qu’un rectangle a une TransformGroup ressource appliquée à sa RenderTransform propriété et que vous souhaitez animer l’une des transformations qu’il contient.
<TransformGroup x:Key="MyTransformGroupResource"
x:Shared="False">
<ScaleTransform />
<RotateTransform />
</TransformGroup>
Pour cibler un Freezable contenu dans une collection, vous utilisez la syntaxe de chemin d’accès suivante.
Syntaxe du chemin |
---|
(
OwnerPropertyArrayIndex).( CollectionChildrenPropertyArrayIndex) [ CollectionIndex].( FreezablePropertyArrayIndex) |
Où CollectionIndex est l’index de l’objet dans son tableau ou sa collection.
Pour cibler la Angle propriété du RotateTransform, la deuxième transformation dans le TransformGroup, vous devez utiliser les éléments suivants Path et PathParameters.
DependencyProperty[] propertyChain =
new DependencyProperty[]
{
Rectangle.RenderTransformProperty,
TransformGroup.ChildrenProperty,
RotateTransform.AngleProperty
};
string thePath = "(0).(1)[1].(2)";
PropertyPath myPropertyPath = new PropertyPath(thePath, propertyChain);
Storyboard.SetTargetProperty(myDoubleAnimation, myPropertyPath);
L’exemple suivant montre le code complet pour animer le Angle d’un RotateTransform contenu dans un TransformGroup.
Rectangle rectangle02 = new Rectangle();
rectangle02.Name = "Rectangle02";
this.RegisterName(rectangle02.Name, rectangle02);
rectangle02.Width = 100;
rectangle02.Height = 100;
rectangle02.Fill = Brushes.Blue;
rectangle02.RenderTransform =
(TransformGroup)this.Resources["MyTransformGroupResource"];
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 0;
myDoubleAnimation.To = 360;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(myDoubleAnimation, rectangle02.Name);
DependencyProperty[] propertyChain =
new DependencyProperty[]
{
Rectangle.RenderTransformProperty,
TransformGroup.ChildrenProperty,
RotateTransform.AngleProperty
};
string thePath = "(0).(1)[1].(2)";
PropertyPath myPropertyPath = new PropertyPath(thePath, propertyChain);
Storyboard.SetTargetProperty(myDoubleAnimation, myPropertyPath);
Storyboard myStoryboard = new Storyboard();
myStoryboard.Children.Add(myDoubleAnimation);
BeginStoryboard myBeginStoryboard = new BeginStoryboard();
myBeginStoryboard.Storyboard = myStoryboard;
EventTrigger myMouseEnterTrigger = new EventTrigger();
myMouseEnterTrigger.RoutedEvent = Rectangle.MouseEnterEvent;
myMouseEnterTrigger.Actions.Add(myBeginStoryboard);
rectangle02.Triggers.Add(myMouseEnterTrigger);
Ciblage indirect avec un freezable comme point de départ
Les sections précédentes ont décrit comment cibler indirectement un Freezable en commençant par un FrameworkElement ou un FrameworkContentElement et en créant une chaîne de propriétés menant à une sous-propriété Freezable. Vous pouvez également utiliser un Freezable point de départ et cibler indirectement l’une de ses Freezable sous-propriétés. Une restriction supplémentaire s’applique lors de l’utilisation d’un Freezable point de départ pour le ciblage indirect : le début Freezable et chaque Freezable entre celui-ci et la sous-propriété ciblée indirectement ne doivent pas être figés.
Contrôle interactif d’un storyboard en XAML
Pour démarrer un storyboard dans XAML (Extensible Application Markup Language), vous utilisez une BeginStoryboard action de déclencheur. BeginStoryboard distribue les animations aux objets et aux propriétés qu’ils animent et démarre le storyboard. (Pour plus d’informations sur ce processus, consultez la vue d’ensemble du système d’animation et de minutage.) Si vous attribuez un BeginStoryboard nom en spécifiant sa Name propriété, vous le rendez un storyboard contrôlable. Vous pouvez ensuite contrôler de manière interactive le storyboard une fois qu’il a démarré. Voici une liste d’actions de storyboard contrôlables que vous utilisez avec des déclencheurs d’événements pour contrôler un storyboard.
PauseStoryboard: met en pause le storyboard.
ResumeStoryboard: reprend un storyboard suspendu.
SetStoryboardSpeedRatio: modifie la vitesse du storyboard.
SkipStoryboardToFill: avance un storyboard jusqu’à la fin de sa période de remplissage, s’il en a un.
StopStoryboard: arrête le storyboard.
RemoveStoryboard: supprime le storyboard.
Dans l’exemple suivant, les actions de storyboard contrôlables sont utilisées pour contrôler de manière interactive un storyboard.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Microsoft.SDK.Animation.ControllableStoryboardExample"
WindowTitle="Fading Rectangle Example">
<StackPanel Margin="10">
<Rectangle
Name="MyRectangle"
Width="100"
Height="100"
Fill="Blue">
</Rectangle>
<Button Name="BeginButton">Begin</Button>
<Button Name="PauseButton">Pause</Button>
<Button Name="ResumeButton">Resume</Button>
<Button Name="SkipToFillButton">Skip To Fill</Button>
<Button Name="StopButton">Stop</Button>
<StackPanel.Triggers>
<EventTrigger RoutedEvent="Button.Click" SourceName="BeginButton">
<BeginStoryboard Name="MyBeginStoryboard">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="(Rectangle.Opacity)"
From="1.0" To="0.0" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="PauseButton">
<PauseStoryboard BeginStoryboardName="MyBeginStoryboard" />
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="ResumeButton">
<ResumeStoryboard BeginStoryboardName="MyBeginStoryboard" />
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="SkipToFillButton">
<SkipStoryboardToFill BeginStoryboardName="MyBeginStoryboard" />
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="StopButton">
<StopStoryboard BeginStoryboardName="MyBeginStoryboard" />
</EventTrigger>
</StackPanel.Triggers>
</StackPanel>
</Page>
Contrôle interactif d’un storyboard à l’aide de code
Les exemples précédents ont montré comment animer à l’aide d’actions de déclencheur. Dans le code, vous pouvez également contrôler un storyboard à l’aide de méthodes interactives de la Storyboard classe. Pour qu’un Storyboard élément soit interactif dans le code, vous devez utiliser la surcharge appropriée de la méthode du Begin storyboard et spécifier true
pour le rendre contrôlable. Pour plus d’informations, consultez la Begin(FrameworkElement, Boolean) page.
La liste suivante montre les méthodes qui peuvent être utilisées pour manipuler une Storyboard fois qu’elle a démarré :
L’avantage d’utiliser ces méthodes est que vous n’avez pas besoin de créer Trigger ou TriggerAction d’objets ; vous avez simplement besoin d’une référence à l’élément contrôlable Storyboard que vous souhaitez manipuler.
Remarque
Toutes les actions interactives effectuées sur un Clock, et donc également sur une Storyboard se produiront lors du prochain cycle du moteur de minutage, qui se produira peu avant le rendu suivant. Par exemple, si vous utilisez la Seek méthode pour passer à un autre point dans une animation, la valeur de propriété ne change pas instantanément, au lieu de cela, la valeur change lors de la graduation suivante du moteur de minutage.
L’exemple suivant montre comment appliquer et contrôler des animations à l’aide des méthodes interactives de la Storyboard classe.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace SDKSample
{
public class ControllableStoryboardExample : Page
{
private Storyboard myStoryboard;
public ControllableStoryboardExample()
{
// Create a name scope for the page.
NameScope.SetNameScope(this, new NameScope());
this.WindowTitle = "Controllable Storyboard Example";
StackPanel myStackPanel = new StackPanel();
myStackPanel.Margin = new Thickness(10);
// Create a rectangle.
Rectangle myRectangle = new Rectangle();
myRectangle.Name = "myRectangle";
// Assign the rectangle a name by
// registering it with the page, so that
// it can be targeted by storyboard
// animations.
this.RegisterName(myRectangle.Name, myRectangle);
myRectangle.Width = 100;
myRectangle.Height = 100;
myRectangle.Fill = Brushes.Blue;
myStackPanel.Children.Add(myRectangle);
//
// Create an animation and a storyboard to animate the
// rectangle.
//
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 1.0;
myDoubleAnimation.To = 0.0;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(5000));
myDoubleAnimation.AutoReverse = true;
// Create the storyboard.
myStoryboard = new Storyboard();
myStoryboard.Children.Add(myDoubleAnimation);
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.OpacityProperty));
//
// Create some buttons to control the storyboard
// and a panel to contain them.
//
StackPanel buttonPanel = new StackPanel();
buttonPanel.Orientation = Orientation.Horizontal;
Button beginButton = new Button();
beginButton.Content = "Begin";
beginButton.Click += new RoutedEventHandler(beginButton_Clicked);
buttonPanel.Children.Add(beginButton);
Button pauseButton = new Button();
pauseButton.Content = "Pause";
pauseButton.Click += new RoutedEventHandler(pauseButton_Clicked);
buttonPanel.Children.Add(pauseButton);
Button resumeButton = new Button();
resumeButton.Content = "Resume";
resumeButton.Click += new RoutedEventHandler(resumeButton_Clicked);
buttonPanel.Children.Add(resumeButton);
Button skipToFillButton = new Button();
skipToFillButton.Content = "Skip to Fill";
skipToFillButton.Click += new RoutedEventHandler(skipToFillButton_Clicked);
buttonPanel.Children.Add(skipToFillButton);
Button setSpeedRatioButton = new Button();
setSpeedRatioButton.Content = "Triple Speed";
setSpeedRatioButton.Click += new RoutedEventHandler(setSpeedRatioButton_Clicked);
buttonPanel.Children.Add(setSpeedRatioButton);
Button stopButton = new Button();
stopButton.Content = "Stop";
stopButton.Click += new RoutedEventHandler(stopButton_Clicked);
buttonPanel.Children.Add(stopButton);
myStackPanel.Children.Add(buttonPanel);
this.Content = myStackPanel;
}
// Begins the storyboard.
private void beginButton_Clicked(object sender, RoutedEventArgs args)
{
// Specifying "true" as the second Begin parameter
// makes this storyboard controllable.
myStoryboard.Begin(this, true);
}
// Pauses the storyboard.
private void pauseButton_Clicked(object sender, RoutedEventArgs args)
{
myStoryboard.Pause(this);
}
// Resumes the storyboard.
private void resumeButton_Clicked(object sender, RoutedEventArgs args)
{
myStoryboard.Resume(this);
}
// Advances the storyboard to its fill period.
private void skipToFillButton_Clicked(object sender, RoutedEventArgs args)
{
myStoryboard.SkipToFill(this);
}
// Updates the storyboard's speed.
private void setSpeedRatioButton_Clicked(object sender, RoutedEventArgs args)
{
// Makes the storyboard progress three times as fast as normal.
myStoryboard.SetSpeedRatio(this, 3);
}
// Stops the storyboard.
private void stopButton_Clicked(object sender, RoutedEventArgs args)
{
myStoryboard.Stop(this);
}
}
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Shapes
Imports System.Windows.Media
Imports System.Windows.Media.Animation
Namespace SDKSample
Public Class ControllableStoryboardExample
Inherits Page
Private myStoryboard As Storyboard
Public Sub New()
' Create a name scope for the page.
NameScope.SetNameScope(Me, New NameScope())
Me.WindowTitle = "Controllable Storyboard Example"
Dim myStackPanel As New StackPanel()
myStackPanel.Margin = New Thickness(10)
' Create a rectangle.
Dim myRectangle As New Rectangle()
myRectangle.Name = "myRectangle"
' Assign the rectangle a name by
' registering it with the page, so that
' it can be targeted by storyboard
' animations.
Me.RegisterName(myRectangle.Name, myRectangle)
myRectangle.Width = 100
myRectangle.Height = 100
myRectangle.Fill = Brushes.Blue
myStackPanel.Children.Add(myRectangle)
'
' Create an animation and a storyboard to animate the
' rectangle.
'
Dim myDoubleAnimation As New DoubleAnimation()
myDoubleAnimation.From = 1.0
myDoubleAnimation.To = 0.0
myDoubleAnimation.Duration = New Duration(TimeSpan.FromMilliseconds(5000))
myDoubleAnimation.AutoReverse = True
' Create the storyboard.
myStoryboard = New Storyboard()
myStoryboard.Children.Add(myDoubleAnimation)
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name)
Storyboard.SetTargetProperty(myDoubleAnimation, New PropertyPath(Rectangle.OpacityProperty))
'
' Create some buttons to control the storyboard
' and a panel to contain them.
'
Dim buttonPanel As New StackPanel()
buttonPanel.Orientation = Orientation.Horizontal
Dim beginButton As New Button()
beginButton.Content = "Begin"
AddHandler beginButton.Click, AddressOf beginButton_Clicked
buttonPanel.Children.Add(beginButton)
Dim pauseButton As New Button()
pauseButton.Content = "Pause"
AddHandler pauseButton.Click, AddressOf pauseButton_Clicked
buttonPanel.Children.Add(pauseButton)
Dim resumeButton As New Button()
resumeButton.Content = "Resume"
AddHandler resumeButton.Click, AddressOf resumeButton_Clicked
buttonPanel.Children.Add(resumeButton)
Dim skipToFillButton As New Button()
skipToFillButton.Content = "Skip to Fill"
AddHandler skipToFillButton.Click, AddressOf skipToFillButton_Clicked
buttonPanel.Children.Add(skipToFillButton)
Dim setSpeedRatioButton As New Button()
setSpeedRatioButton.Content = "Triple Speed"
AddHandler setSpeedRatioButton.Click, AddressOf setSpeedRatioButton_Clicked
buttonPanel.Children.Add(setSpeedRatioButton)
Dim stopButton As New Button()
stopButton.Content = "Stop"
AddHandler stopButton.Click, AddressOf stopButton_Clicked
buttonPanel.Children.Add(stopButton)
myStackPanel.Children.Add(buttonPanel)
Me.Content = myStackPanel
End Sub
' Begins the storyboard.
Private Sub beginButton_Clicked(ByVal sender As Object, ByVal args As RoutedEventArgs)
' Specifying "true" as the second Begin parameter
' makes this storyboard controllable.
myStoryboard.Begin(Me, True)
End Sub
' Pauses the storyboard.
Private Sub pauseButton_Clicked(ByVal sender As Object, ByVal args As RoutedEventArgs)
myStoryboard.Pause(Me)
End Sub
' Resumes the storyboard.
Private Sub resumeButton_Clicked(ByVal sender As Object, ByVal args As RoutedEventArgs)
myStoryboard.Resume(Me)
End Sub
' Advances the storyboard to its fill period.
Private Sub skipToFillButton_Clicked(ByVal sender As Object, ByVal args As RoutedEventArgs)
myStoryboard.SkipToFill(Me)
End Sub
' Updates the storyboard's speed.
Private Sub setSpeedRatioButton_Clicked(ByVal sender As Object, ByVal args As RoutedEventArgs)
' Makes the storyboard progress three times as fast as normal.
myStoryboard.SetSpeedRatio(Me, 3)
End Sub
' Stops the storyboard.
Private Sub stopButton_Clicked(ByVal sender As Object, ByVal args As RoutedEventArgs)
myStoryboard.Stop(Me)
End Sub
End Class
End Namespace
Animer dans un style
Vous pouvez utiliser des Storyboard objets pour définir des animations dans un Style. L’animation avec un Storyboard dans un Style est similaire à l’utilisation d’un Storyboard autre emplacement, avec les trois exceptions suivantes :
Vous ne spécifiez pas un TargetName; l’élément Storyboard cible toujours l’élément auquel il Style est appliqué. Pour cibler Freezable des objets, vous devez utiliser le ciblage indirect. Pour plus d’informations sur le ciblage indirect, consultez la section Ciblage indirect .
Vous ne pouvez pas spécifier un SourceName pour un EventTrigger ou un Trigger.
Vous ne pouvez pas utiliser de références de ressources dynamiques ni d’expressions de liaison de données pour définir les valeurs de propriété de Storyboard ou d'animation. C’est parce que tout à l’intérieur d’un Style doit être sûr pour les threads, et le système de minutage doit FreezeStoryboard les objets pour les rendre sûrs pour les threads. Un Storyboard ne peut être figé si lui ou ses chronologies enfants contiennent des références de ressources dynamiques ou des expressions de liaison de données. Pour plus d’informations sur le gel et d’autres Freezable fonctionnalités, consultez la vue d’ensemble des objets freezables.
En XAML, vous ne pouvez pas déclarer de gestionnaires d’événements pour Storyboard ou d’événements d’animation.
Pour obtenir un exemple montrant comment définir un storyboard dans un style, consultez l’exemple Animer dans un style .
Animer dans un ControlTemplate
Vous pouvez utiliser des Storyboard objets pour définir des animations dans un ControlTemplate. L’animation avec un Storyboard dans un ControlTemplate est similaire à l’utilisation d’un Storyboard autre emplacement, avec les deux exceptions suivantes :
Le TargetName ne peut faire référence qu'aux objets enfants du ControlTemplate. Si TargetName n'est pas spécifié, l'animation cible l'élément sur lequel ControlTemplate est appliqué.
Le SourceName pour un EventTrigger ou un Trigger peut uniquement faire référence aux objets enfants de l’objet ControlTemplate.
Vous ne pouvez pas utiliser de références de ressources dynamiques ni d’expressions de liaison de données pour définir les valeurs de propriété de Storyboard ou d'animation. C’est parce que tout à l’intérieur d’un ControlTemplate doit être sûr pour les threads, et le système de minutage doit FreezeStoryboard les objets pour les rendre sûrs pour les threads. Un Storyboard ne peut être figé si lui ou ses chronologies enfants contiennent des références de ressources dynamiques ou des expressions de liaison de données. Pour plus d’informations sur le gel et d’autres Freezable fonctionnalités, consultez la vue d’ensemble des objets freezables.
En XAML, vous ne pouvez pas déclarer de gestionnaires d’événements pour Storyboard ou d’événements d’animation.
Pour obtenir un exemple montrant comment définir un storyboard dans un ControlTemplate, consultez l’exemple Animate dans un ControlTemplate .
Animer lorsque la valeur d'une propriété change
Dans les styles et les modèles de contrôle, vous pouvez utiliser des objets déclencheur pour démarrer un storyboard lorsqu'une propriété change. Pour obtenir des exemples, consultez Déclencher une animation lorsqu’une valeur de propriété change et s’anime dans un ControlTemplate.
Les animations appliquées par les objets de propriété Trigger se comportent de manière plus complexe que les animations EventTrigger ou celles lancées à l'aide des méthodes Storyboard. Ils effectuent une « transition » avec des animations définies par d'autres Trigger objets, mais composent avec des animations EventTrigger déclenchées par des méthodes.
Voir aussi
- Vue d'ensemble de l’animation
- Vue d’ensemble des techniques d’animation de propriétés
- Vue d’ensemble des objets gelables
.NET Desktop feedback