Animazioni con fotogrammi chiave e con funzioni di interpolazioneKey-frame animations and easing function animations

Le animazioni con fotogrammi chiave lineari, le animazioni con fotogrammi chiave con un valore KeySpline e le funzioni di interpolazione sono tre tecniche diverse utilizzabili sostanzialmente nello stesso scenario, ovvero la creazione di un'animazione con storyboard un po' più complessa, che passa da uno stato di partenza a uno di arrivo seguendo un comportamento non lineare.Linear key-frame animations, key-frame animations with a KeySpline value, or easing functions are three different techniques for approximately the same scenario: creating a storyboarded animation that's a bit more complex, and that uses a nonlinear animation behavior from a starting state to an end state.

PrerequisitiPrerequisites

Assicurati di aver letto l'argomento relativo alle animazioni con storyboard,Make sure you've read the Storyboarded animations topic. Questo argomento amplia i concetti di animazione illustrati nell'argomento relativo alle animazioni con storyboard, senza riepilogarli.This topic builds on the animation concepts that were explained in Storyboarded animations and won't go over them again. Ad esempio, l'argomento sulle animazioni con storyboard descrive come impostare la destinazione di animazioni, le storyboard come risorse e i valori della proprietà Timeline come Duration, FillBehavior e così via.For example, Storyboarded animations describes how to target animations, storyboards as resources, the Timeline property values such as Duration, FillBehavior, and so on.

Animazioni con fotogrammi chiaveAnimating using key-frame animations

Le animazioni con fotogrammi chiave consentono più di un valore di destinazione raggiunto lungo la sequenza temporale dell'animazione.Key-frame animations permit more than one target value that is reached at a point along the animation timeline. In altre parole, ogni fotogramma chiave può specificare un valore intermedio diverso e l'ultimo fotogramma chiave raggiunto corrisponde al valore di animazione finale.In other words, each key frame can specify a different intermediate value, and the last key frame reached is the final animation value. Specificando più valori da animare è possibile creare animazioni più complesse.By specifying multiple values to animate, you can make more complex animations. Le animazioni con fotogrammi chiave abilitano inoltre diverse logiche di interpolazione, ciascuna delle quali viene implementata con una sottoclasse KeyFrame diversa per ogni tipo di animazione.Key-frame animations also enable different interpolation logic, which are each implemented as a different KeyFrame subclass per animation type. In particolare, ciascun tipo di animazione con fotogrammi chiave dispone di una variante Discrete, Linear, Spline e Easing della relativa classe KeyFrame per specificare i propri fotogrammi chiave.Specifically, each key-frame animation type has a Discrete, Linear, Spline and Easing variation of its KeyFrame class for specifying its key frames. Ad esempio, per specificare un'animazione destinata a un valore Double e che utilizza fotogrammi chiave, è possibile dichiarare fotogrammi chiave con DiscreteDoubleKeyFrame, LinearDoubleKeyFrame, SplineDoubleKeyFramee EasingDoubleKeyFrame.For example, to specify an animation that targets a Double and uses key frames, you could declare key frames with DiscreteDoubleKeyFrame, LinearDoubleKeyFrame, SplineDoubleKeyFrame, and EasingDoubleKeyFrame. Puoi usare uno qualsiasi o tutti questi tipi all'interno di un'unica raccolta KeyFrames per modificare l'interpolazione ogni volta che viene raggiunto un fotogramma chiave.You can use any and all of these types within a single KeyFrames collection, to change the interpolation each time a new key frame is reached.

Per quanto riguarda il comportamento dell'interpolazione, ogni fotogramma chiave controlla l'interpolazione finché non viene raggiunto il valore di KeyTime.For interpolation behavior, each key frame controls the interpolation until its KeyTime time is reached. In quel momento viene raggiunto anche il relativo valore Value.Its Value is reached at that time also. Se oltre questo punto sono presenti altri fotogrammi chiave, questo valore diventa il valore iniziale del successivo fotogramma chiave in sequenza.If there are more key frames beyond, the value then becomes the starting value for the next key frame in a sequence.

All'inizio dell'animazione, se non esistono fotogrammi chiave con KeyTime pari a "0:0:0", il valore iniziale coincide con il valore non animato della proprietà, qualunque esso sia.At the start of the animation, if no key frame with KeyTime of "0:0:0" exists, the starting value is whatever the non-animated value of the property is. Questo comportamento è simile al modo in cui un'animazione daa da viene eseguita / To / By se non è presente alcuna da.This is similar to how a From/To/By animation acts if there is no From.

La durata di un'animazione con fotogrammi chiave coincide in modo implicito con la durata pari al valore di KeyTime più alto impostato in uno qualunque dei relativi fotogrammi chiave.The duration of a key-frame animation is implicitly the duration equal to the highest KeyTime value set in any of its key frames. Se vuoi, puoi anche impostare un valore esplicito per la proprietà Duration, ma fai attenzione che non sia inferiore al valore di KeyTime dei tuoi fotogrammi chiave, altrimenti parte dell'animazione verrà troncata.You can set an explicit Duration if you want, but be careful it's not shorter than a KeyTime in your own key frames or you'll cut off part of the animation.

Oltre alla proprietà Duration, puoi impostare tutte le proprietà di un'animazione con fotogrammi chiave basate su Timeline, proprio come faresti con un'animazione From/To/By, perché anche le classi delle animazioni con fotogrammi chiave derivano da Timeline.In addition to Duration, you can set all the Timeline based properties on a key-frame animation, like you can with a From/To/By animation, because the key-frame animation classes also derive from Timeline. Si tratta di:These are:

  • AutoReverse: una volta raggiunto l'ultimo fotogramma chiave, i frame vengono ripetuti in ordine inverso rispetto alla fine.AutoReverse: once the last key frame is reached, the frames are repeated in reverse order from the end. In questo modo la durata apparente dell'animazione viene raddoppiata.This doubles the apparent duration of the animation.
  • BeginTime: ritarda l'avvio dell'animazione.BeginTime: delays the start of the animation. La sequenza temporale dei valori KeyTime contenuti nei fotogrammi non avvia il conteggio finché non viene raggiunto BeginTime. In questo modo si evita il rischio di troncare i fotogrammiThe timeline for the KeyTime values in the frames doesn't start counting until BeginTime is reached, so there's no risk of cutting off frames
  • FillBehavior: determina cosa accade quando viene raggiunto l'ultimo fotogramma chiave.FillBehavior: controls what happens when the last key frame is reached. FillBehavior non ha effetto su nessuno dei fotogrammi chiave intermedi.FillBehavior has no effect on any intermediate key frames.
  • RepeatBehavior:RepeatBehavior:
    • Se impostato su Forever, i fotogrammi chiave e la relativa sequenza temporale si ripetono all'infinito.If set to Forever, then the key frames and their timeline repeat infinitely.
    • Se impostato su un certo numero di interazioni, la sequenza temporale si ripeterà per un pari numero di volte.If set to an iteration count, the timeline repeats that many times.
    • Se impostato su un valore Duration, la sequenza temporale si ripete fino a quando non viene raggiunto tale intervallo.If set to a Duration, the timeline repeats until that time is reached. In questo modo l'animazione potrebbe risultare parzialmente troncata durante la sequenza dei fotogrammi chiave se il valore specificato non è un fattore intero della durata implicita della sequenza temporale.This might truncate the animation part way through the key frame sequence, if it's not an integer factor of the timeline's implicit duration.
  • SpeedRatio (generalmente non usato)SpeedRatio (not commonly used)

Fotogrammi chiave lineariLinear key frames

I fotogrammi chiave lineari producono un'interpolazione lineare semplice del valore fino al raggiungimento del KeyTime del fotogramma.Linear key frames result in a simple linear interpolation of the value until the frame's KeyTime is reached. Questo comportamento di interpolazione è il più simile alle animazioni più semplici da / ada quelle / By descritte nell'argomento animazioni con storyboard .This interpolation behavior is the most similar to the simpler From/To/By animations described in the Storyboarded animations topic.

Ecco come usare un'animazione con fotogrammi chiave per ridimensionare l'altezza di rendering di un rettangolo tramite fotogrammi chiave lineari.Here's how to use a key-frame animation to scale the render height of a rectangle, using linear key frames. Questo esempio esegue un'animazione nel punto in cui l'altezza del rettangolo aumenta leggermente e in modo lineare per i primi 4 secondi, per poi ridimensionarsi rapidamente nell'ultimo secondo fino a che il rettangolo non raddoppia l'altezza iniziale.This example runs an animation where the height of the rectangle increases slightly and linearly for the first 4 seconds, then scales rapidly for the last second until the rectangle is double the starting height.

<StackPanel>
    <StackPanel.Resources>
        <Storyboard x:Name="myStoryboard">
            <DoubleAnimationUsingKeyFrames
              Storyboard.TargetName="myRectangle"
              Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
                <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>
                <LinearDoubleKeyFrame Value="1.2" KeyTime="0:0:4"/>
                <LinearDoubleKeyFrame Value="2" KeyTime="0:0:5"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </StackPanel.Resources>
</StackPanel>

Fotogrammi chiave discretiDiscrete key frames

I fotogrammi chiave discreti non fanno uso di interpolazioni.Discrete key frames don't use any interpolation at all. Quando si raggiunge il valore di KeyTime viene semplicemente applicato il nuovo valore Value.When a KeyTime is reached, the new Value is simply applied. A seconda della proprietà dell'interfaccia utente a cui viene applicata l'animazione, spesso si creano animazioni che sembrano "saltare".Depending on which UI property is being animated, this often produces an animation that appears to "jump". Assicurati che questo sia esattamente il comportamento che desideri ottenere.Be certain that this is the aesthetic behavior that you really want. Puoi ridurre al minimo l'effetto salto aumentando i numero dei fotogrammi chiave che dichiari, ma se il tuo obiettivo è ottenere un'animazione fluida, ti consigliamo di utilizzare invece i fotogrammi chiave lineari o spline.You can minimize the apparent jumps by increasing the number of key frames you declare, but if a smooth animation is your goal, you might be better off using linear or spline key frames instead.

Nota

I fotogrammi chiave discreti sono l'unico modo per animare un valore che non è di tipo Double, Pointe colorcon DiscreteObjectKeyFrame.Discrete key frames are the only way to animate a value that isn't of type Double, Point, and Color, with a DiscreteObjectKeyFrame. Approfondiremo questo aspetto più avanti nel corso dell'argomento.We'll discuss this in more detail later in this topic.

Fotogrammi chiave splineSpline key frames

Un fotogramma chiave spline crea una transizione variabile tra i valori in base al valore della proprietà KeySpline .A spline key frame creates a variable transition between values according to the value of the KeySpline property. Questa proprietà specifica il primo e il secondo punto di controllo di una curva di Bézier che descrive l'accelerazione dell'animazione.This property specifies the first and second control points of a Bezier curve, which describes the acceleration of the animation. In sostanza, un oggetto KeySpline definisce una relazione di funzione sul tempo in cui il grafico in fase di funzione è la forma di tale curva di Bezier.Basically, a KeySpline defines a function-over-time relationship where the function-time graph is the shape of that Bezier curve. In genere si specifica un valore KeySpline in una stringa di attributo a sintassi abbreviata XAML con quattro valori Double separati da spazi o virgole.You typically specify a KeySpline value in a XAML shorthand attribute string that has four Double values separated by spaces or commas. Questi valori sono le coppie "X,Y" relative a due punti di controllo della curva di Bézier.These values are "X,Y" pairs for two control points of the Bezier curve. "X" indica il tempo, mentre "Y" indica il fattore di modifica della funzione rispetto al valore."X" is time and "Y" is the function modifier to the value. Ogni valore deve sempre essere compreso tra 0 e 1 inclusi.Each value should always be between 0 and 1 inclusive. Senza la modifica del punto di controllo di KeySpline, la linea retta compresa tra 0,0 e 1,1 è la rappresentazione di una funzione nel tempo per un'interpolazione lineare.Without control point modification to a KeySpline, the straight line from 0,0 to 1,1 is the representation of a function over time for a linear interpolation. I punti di controllo modificano la forma della curva e di conseguenza il comportamento della funzione nel tempo relativamente all'animazione spline.Your control points change the shape of that curve and thus the behavior of the function over time for the spline animation. Probabilmente questo concetto è più chiaro se visualizzato sotto forma di grafico.It's probably best to see this visually as a graph. Puoi eseguire l'esempio di visualizzatore spline chiave di Silverlight nel browser per visualizzare il modo in cui i punti di controllo modificano la curva e come si comporta l'animazione di esempio quando la si usa come valore KeySpline.You can run the Silverlight key-spline visualizer sample in a browser to see how the control points modify the curve and how a sample animation runs when using it as a KeySpline value.

Il prossimo esempio mostra tre diversi fotogrammi chiave applicati a un'animazione, dove l'ultimo costituisce l'animazione spline chiave di un valore Double (SplineDoubleKeyFrame).This next example shows three different key frames applied to an animation, with the last one being a key spline animation for a Double value (SplineDoubleKeyFrame). Tieni presente la stringa "0.6,0.0 0.9,0.00" applicata per KeySpline.Note the string "0.6,0.0 0.9,0.00" applied for KeySpline. In questo modo si produce una curva per cui l'animazione all'inizio sembra procedere lentamente, per poi raggiungere rapidamente il valore proprio prima di raggiungere KeyTime.This produces a curve where the animation appears to run slowly at first but then rapidly reaches the value just before the KeyTime is reached.

<Storyboard x:Name="myStoryboard">
    <!-- Animate the TranslateTransform's X property
        from 0 to 350, then 50,
        then 200 over 10 seconds. -->
    <DoubleAnimationUsingKeyFrames
        Storyboard.TargetName="MyAnimatedTranslateTransform"
        Storyboard.TargetProperty="X"
        Duration="0:0:10" EnableDependentAnimation="True">

        <!-- Using a LinearDoubleKeyFrame, the rectangle moves 
            steadily from its starting position to 500 over 
            the first 3 seconds.  -->
        <LinearDoubleKeyFrame Value="500" KeyTime="0:0:3"/>

        <!-- Using a DiscreteDoubleKeyFrame, the rectangle suddenly 
            appears at 400 after the fourth second of the animation. -->
        <DiscreteDoubleKeyFrame Value="400" KeyTime="0:0:4"/>

        <!-- Using a SplineDoubleKeyFrame, the rectangle moves 
            back to its starting point. The
            animation starts out slowly at first and then speeds up. 
            This KeyFrame ends after the 6th second. -->
        <SplineDoubleKeyFrame KeySpline="0.6,0.0 0.9,0.00" Value="0" KeyTime="0:0:6"/>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

Fotogrammi chiave d'interpolazioneEasing key frames

Un fotogramma chiave di interpolazione è un fotogramma chiave in cui viene applicata l'interpolazione e la funzione nel tempo dell'interpolazione viene controllata da diverse formule matematiche predefinite.An easing key frame is a key frame where interpolation is being applied, and the function over time of the interpolation is controlled by several pre-defined mathematical formulas. È possibile produrre in realtà lo stesso risultato con un fotogramma chiave spline come si può fare con alcuni dei tipi di funzione di interpolazione, ma sono presenti anche alcune funzioni di interpolazione, ad esempio BackEase, che non è possibile riprodurre con una spline.You can actually produce much the same result with a spline key frame as you can with some of the easing function types, but there are also some easing functions, such as BackEase, that you can't reproduce with a spline.

Per applicare una funzione d'interpolazione a un fotogramma chiave d'interpolazione, devi impostare la proprietà EasingFunction come elemento di proprietà di quel fotogramma chiave nel codice XAML.To apply an easing function to an easing key frame, you set the EasingFunction property as a property element in XAML for that key frame. Per quanto riguarda il valore, specifica un elemento oggetto per uno dei tipi di funzione d'interpolazione.For the value, specify an object element for one of the easing function types.

Questo esempio si applica a CubicEase e quindi a BounceEase come fotogrammi chiave successivi a DoubleAnimation per creare un effetto di rimbalzo.This example applies a CubicEase and then a BounceEase as successive key frames to a DoubleAnimation to create a bouncing effect.

<Storyboard x:Name="myStoryboard">
    <DoubleAnimationUsingKeyFrames Duration="0:0:10"
        Storyboard.TargetProperty="Height"
        Storyboard.TargetName="myEllipse">

        <!-- This keyframe animates the ellipse up to the crest 
            where it slows down and stops. -->
        <EasingDoubleKeyFrame Value="-300" KeyTime="00:00:02">
            <EasingDoubleKeyFrame.EasingFunction>
                <CubicEase/>
            </EasingDoubleKeyFrame.EasingFunction>
        </EasingDoubleKeyFrame>

        <!-- This keyframe animates the ellipse back down and makes
            it bounce. -->
        <EasingDoubleKeyFrame Value="0" KeyTime="00:00:06">
            <EasingDoubleKeyFrame.EasingFunction>
                <BounceEase Bounces="5"/>
            </EasingDoubleKeyFrame.EasingFunction>
        </EasingDoubleKeyFrame>
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

Questo è solo un esempio di funzione d'interpolazione,This is just one easing function example. ne troverai altri nella prossima sezione.We'll cover more in the next section.

Funzioni di interpolazioneEasing functions

Le funzioni di interpolazione consentono di applicare formule matematiche personalizzate alle animazioni.Easing functions allow you to apply custom mathematical formulas to your animations. Le operazioni matematiche spesso consentono di produrre animazioni che simulano situazioni fisiche reali in un sistema di coordinate bidimensionale.Mathematical operations are often useful to produce animations that simulate real-world physics in a 2-D coordinate system. Si può ad esempio fare in modo che un oggetto rimbalzi in modo realistico o si comporti come se fosse su una molla.For example, you may want an object to realistically bounce or behave as though it were on a spring. È possibile usare il fotogramma chiave o anche da / a / tramite animazioni per approssimare questi effetti, ma la quantità di lavoro necessaria è molto elevata e l'animazione sarebbe meno accurata rispetto all'uso di una formula matematica.You could use key frame or even From/To/By animations to approximate these effects but it would take a significant amount of work and the animation would be less accurate than using a mathematical formula.

Le funzioni di interpolazione si possono applicare alle animazioni in tre modi:Easing functions can be applied to animations in three ways:

Ecco l'elenco delle funzioni di interpolazione:Here is a list of the easing functions:

  • BackEase: ritrae leggermente il movimento di un'animazione prima di iniziare ad aggiungere un'animazione nel percorso indicato.BackEase: Retracts the motion of an animation slightly before it begins to animate in the path indicated.
  • BounceEase: crea un effetto di rimbalzo.BounceEase: Creates a bouncing effect.
  • CircleEase: crea un'animazione che accelera o decelera utilizzando una funzione circolare.CircleEase: Creates an animation that accelerates or decelerates using a circular function.
  • CubicEase: crea un'animazione che accelera o decelera usando la formula f (t) = T3.CubicEase: Creates an animation that accelerates or decelerates using the formula f(t) = t3.
  • ElasticEase: crea un'animazione simile a una molla che oscilla avanti e indietro fino a quando non passa a Rest.ElasticEase: Creates an animation that resembles a spring oscillating back and forth until it comes to rest.
  • ExponentialEase: crea un'animazione che accelera o decelera utilizzando una formula esponenziale.ExponentialEase: Creates an animation that accelerates or decelerates using an exponential formula.
  • PowerEase: crea un'animazione che accelera o decelera usando la formula f (t) = TP dove p è uguale alla proprietà di risparmio energia .PowerEase: Creates an animation that accelerates or decelerates using the formula f(t) = tp where p is equal to the Power property.
  • QuadraticEase: crea un'animazione che accelera o decelera usando la formula f (t) = T2.QuadraticEase: Creates an animation that accelerates or decelerates using the formula f(t) = t2.
  • QuarticEase: crea un'animazione che accelera o decelera usando la formula f (t) = T4.QuarticEase: Creates an animation that accelerates or decelerates using the formula f(t) = t4.
  • QuinticEase: crea un'animazione che accelera o decelera usando la formula f (t) = T5.QuinticEase: Create an animation that accelerates or decelerates using the formula f(t) = t5.
  • SineEase: crea un'animazione che accelera o rallenta usando una formula seno.SineEase: Creates an animation that accelerates or decelerates using a sine formula.

Alcune funzioni di interpolazione dispongono di proprietà specifiche.Some of the easing functions have their own properties. Ad esempio, BounceEase ha due proprietà, Bounces e Bounciness, che modificano il comportamento di funzione nel tempo di quella determinata funzione BounceEase.For example, BounceEase has two properties Bounces and Bounciness that modify the function-over-time behavior of that particular BounceEase. Altre funzioni di interpolazione, come CubicEase, hanno solo la proprietà EasingMode, comune a tutte le funzioni di interpolazione, che produce sempre lo stesso comportamento di funzione nel tempo.Other easing functions such as CubicEase don't have properties other than the EasingMode property that all easing functions share, and always produce the same function-over-time behavior.

Alcune di queste funzioni di interpolazione possono sovrapporsi leggermente, in base a come imposti le proprietà e le funzioni di interpolazione che dispongono di proprietà.Some of these easing functions have a bit of overlap, depending on how you set properties on the easing functions that have properties. Ad esempio, QuadraticEase è esattamente uguale a un PowerEase con potenza uguale a 2.For example, QuadraticEase is exactly the same as a PowerEase with Power equal to 2. E CircleEase è fondamentalmente un valore predefinito di ExponentialEase.And CircleEase is basically a default-value ExponentialEase.

La funzione di interpolazione BackEase è invece unica perché può modificare il valore al di là del normale intervallo impostato da From/To o dai valori dei fotogrammi chiave.The BackEase easing function is unique because it can change the value outside of the normal range as set by From/To or values of key frames. Viene avviata l'animazione modificando il valore nella direzione opposta come previsto da un comportamento normale da / a , viene restituito nuovamente il valore from o starting, quindi l'animazione viene eseguita come di consueto.It starts the animation by changing the value in the opposite direction as would be expected from a normal From/To behavior, goes back to the From or starting value again, and then runs the animation as normal.

In un esempio precedente ti abbiamo mostrato come dichiarare una funzione di interpolazione per un'animazione con fotogrammi chiave.In an earlier example, we showed how to declare an easing function for a key-frame animation. Nell'esempio seguente viene applicata una funzione di interpolazione a un'animazione da / a / da .This next sample applies an easing function to a From/To/By animation.

<StackPanel x:Name="LayoutRoot" Background="White">
    <StackPanel.Resources>
        <Storyboard x:Name="myStoryboard">
            <DoubleAnimation From="30" To="200" Duration="00:00:3" 
                Storyboard.TargetName="myRectangle" 
                Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
                <DoubleAnimation.EasingFunction>
                    <BounceEase Bounces="2" EasingMode="EaseOut" 
                                Bounciness="2"/>
                </DoubleAnimation.EasingFunction>
            </DoubleAnimation>
        </Storyboard>
    </StackPanel.Resources>
    <Rectangle x:Name="myRectangle" Fill="Blue" Width="200" Height="30"/>
</StackPanel>

Quando viene applicata una funzione di interpolazione a un'animazione da / a / da, vengono modificate le caratteristiche della funzione inbase al tempo che interpolano tra i valori from e to per la durata dell'animazione.When an easing function is applied to a From/To/By animation, it's changing the function- over-time characteristics of how the value interpolates between the From and To values over the Duration of the animation. Se non ci fosse la funzione di interpolazione si tratterebbe di un'interpolazione lineare.Without an easing function, that would be a linear interpolation.

Animazioni con valori di oggetti discretiDiscrete object value animations

C'è un tipo di animazione che merita un'attenzione speciale perché rappresenta l'unico modo per applicare un valore animato alle proprietà di tipo diverso da Double, Point o Color.One type of animation deserves special mention because it's the only way you can apply an animated value to properties that aren't of type Double, Point, or Color. Si tratta del ObjectAnimationUsingKeyFramesdi animazione con fotogrammi chiave.This is the key-frame animation ObjectAnimationUsingKeyFrames. Applicare animazioni usando valori Object è diverso, perché non dà alcuna possibilità di interpolare i valori tra un fotogramma e l'altro.Animating using Object values is different because there's no possibility of interpolating the values between the frames. Quando viene raggiunto il valore KeyTime del fotogramma, il valore animato viene immediatamente impostato sul valore specificato nella proprietà Value del fotogramma chiave.When the frame's KeyTime is reached, the animated value is immediately set to the value specified in the key frame's Value. Siccome non c'è interpolazione, nella raccolta di fotogrammi chiave ObjectAnimationUsingKeyFrames usi un solo fotogramma chiave, e cioè DiscreteObjectKeyFrame.Because there's no interpolation, there's only one key frame you use in the ObjectAnimationUsingKeyFrames key frames collection: DiscreteObjectKeyFrame.

In genere la proprietà Value di un DiscreteObjectKeyFrame viene impostata usando la sintassi degli elementi di proprietà, dato che spesso non è possibile esprimere come stringa il valore Object che stai tentando di impostare per la proprietà Value della sintassi dell'attributo.The Value of a DiscreteObjectKeyFrame is often set using property element syntax, because the object value you are trying to set often is not expressible as a string to fill Value in attribute syntax. Puoi comunque usare la sintassi dell'attributo se fai ricorso a un riferimento come StaticResource.You can still use attribute syntax if you use a reference such as StaticResource.

Un oggetto ObjectAnimationUsingKeyFrames viene usato nei modelli predefiniti quando una proprietà del modello fa riferimento a una risorsa Brush.One place you'll see an ObjectAnimationUsingKeyFrames used in the default templates is when a template property references a Brush resource. Queste risorse sono oggetti SolidColorBrush, non solo un valore Color, e usano risorse definite come temi di sistema (ThemeDictionaries).These resources are SolidColorBrush objects, not just a Color value, and they use resources that are defined as system themes (ThemeDictionaries). Possono essere assegnate direttamente a un valore di tipo Brush come TextBlock.Foreground e non devono ricorrere alla selezione indiretta della destinazione.They can be assigned directly to a Brush-type value such as TextBlock.Foreground and don't need to use indirect targeting. Ma siccome un SolidColorBrush non è Double, Point o Color, per usare la risorsa devi ricorrere a un ObjectAnimationUsingKeyFrames.But because a SolidColorBrush is not Double, Point, or Color, you have to use a ObjectAnimationUsingKeyFrames to use the resource.

<Style x:Key="TextButtonStyle" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Grid Background="Transparent">
                    <TextBlock x:Name="Text"
                        Text="{TemplateBinding Content}"/>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="PointerOver">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPointerOverForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Text" Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ApplicationPressedForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
...
                       </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Puoi anche usare la classe ObjectAnimationUsingKeyFrames per animare le proprietà che fanno uso di un valore di enumerazione.You also might use ObjectAnimationUsingKeyFrames to animate properties that use an enumeration value. Ecco un altro esempio per uno stile denominato tratto dai modelli predefiniti di Windows Runtime.Here's another example from a named style that comes from the Windows Runtime default templates. Come puoi notare viene impostata la proprietà Visibility, che accetta una costante di enumerazione Visibility.Note how it sets the Visibility property that takes a Visibility enumeration constant. In questo caso puoi impostare il valore usando la sintassi dell'attributo.In this case you can set the value using attribute syntax. Per impostare una proprietà con un valore di enumerazione hai solo bisogno del nome non qualificato di costante dell'enumerazione, ad esempio "Collapsed".You only need the unqualified constant name from an enumeration for setting a property with an enumeration value, for example "Collapsed".

<Style x:Key="BackButtonStyle" TargetType="Button">
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="Button">
          <Grid x:Name="RootGrid">
            <VisualStateManager.VisualStateGroups>
              <VisualStateGroup x:Name="CommonStates">
              <VisualState x:Name="Normal"/>
...           <VisualState x:Name="Disabled">
                <Storyboard>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Visibility">
                    <DiscreteObjectKeyFrame Value="Collapsed" KeyTime="0"/>
                  </ObjectAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
            </VisualStateGroup>
...
          </VisualStateManager.VisualStateGroups>
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

Puoi usare più DiscreteObjectKeyFrame per un set di fotogrammi ObjectAnimationUsingKeyFrames,You can use more than one DiscreteObjectKeyFrame for an ObjectAnimationUsingKeyFrames frame set. Questo potrebbe essere un modo interessante per creare un'animazione "Slide Show" animando il valore di Image. Source, come scenario di esempio in cui possono essere utili più valori di oggetti.This might be an interesting way to create a "slide show" animation by animating the value of Image.Source, as an example scenario for where multiple object values might be useful.