Applicazioni di animazioni storyboard a più oggetti XAML

Applies to Windows and Windows Phone

Ecco come evitare di dover creare più animazioni storyboard, applicando invece lo stesso storyboard a più oggetti.

Esaminiamo questa pagina XAML presa da un'app, in cui viene mostrata una griglia di immagini del tastierino numerico. Il nostro obiettivo è di animare questi pulsanti in modo da far sembrare che si muovano quando l'utente li tocca.

Un file XAML con più pulsanti: è davvero necessario creare un'animazione storyboard per ciascuno di loro?

Come descritto nell'argomento Applicazione di interfacce e animazioni a un pulsante, a differenza di iOS in cui vengono variati i parametri, ad esempio l'opacità nel tempo in un blocco di animazioni, in Windows 8 si usano oggetti storyboard. Se su schermo hai vari oggetti XAML simili, ad esempio la nostra griglia di pulsanti, potresti chiederti se è necessario creare uno storyboard per ciascun oggetto. La buona notizia è che non è necessario e ora vediamo come applicare la stessa animazione a più oggetti.

Nota   Ricorda che in Windows 8 uno storyboard è un'animazione, non un modo di disporre la tua applicazione come in Xcode.

Il segreto sta nel modificare la proprietà TargetName dello storyboard a livello di programmazione, come illustrato nell'esempio seguente.

Definizione dello storyboard

Definisci innanzitutto l'animazione storyboard. Puoi usare Blend o definirla manualmente in XAML. Per un esempio con l'uso di Blend, vedi Applicazione di interfacce e animazioni a un pulsante. Se usi Blend, rimuovi qualsiasi proprietà TargetName. Altrimenti l'animazione verrà applicata solo a quella specifica destinazione. Ecco un esempio:


    <Page.Resources>
        <Storyboard x:Name="TapAnimation">
			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" >
				<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
				<EasingDoubleKeyFrame KeyTime="0:0:0.05" Value="0.95"/>
				<EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="1"/>
			</DoubleAnimationUsingKeyFrames>
			<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" >
				<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
				<EasingDoubleKeyFrame KeyTime="0:0:0.05" Value="0.95"/>
				<EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="1"/>
			</DoubleAnimationUsingKeyFrames>
		</Storyboard>
    </Page.Resources>

Ricorda ti aggiungere un tag <RenderTransform> a qualsiasi oggetto XAML che verrà modificato dallo storyboard, nonché un segnaposto per la trasformazione specifica che verrà animata, altrimenti l'app genererà un'eccezione. Ecco un esempio di oggetto Image a cui può essere applicato lo storyboard:


 <Image x:Name="myImage" Width="256" Height="160" RenderTransformOrigin= "0.5,0.5" >
                        <Image.RenderTransform>
                            <CompositeTransform/>
                        </Image.RenderTransform>
                    </Image>

Nota  L'uso della proprietà RenderTransformOrigin= "0.5,0.5" garantisce che ogni animazione sia centrata a metà dell'oggetto.

Applicazione dello storyboard

Successivamente associa lo storyboard a un oggetto e attivalo in base alle esigenze. Attenzione: non puoi modificare la proprietà TargetName durante la riproduzione dell'animazione. Altrimenti l'app genererà un'eccezione. Per evitare questa situazione, chiama Stop() prima di modificare la destinazione.

Suggerimento  Una chiamata a GetCurrentState() può permettere di rilevare se uno storyboard è attualmente in esecuzione.

Questo è il codice per attivare l'animazione di uno specifico oggetto Image. Ad esempio, questo codice potrebbe essere usato in risposta al tocco dell'immagine da parte dell'utente, mediante un evento PointerPressed. È altrettanto semplice applicarlo a un Button, usando un evento Click.


 // Add using Windows.UI.Xaml.Media.Animation;
            TapAnimation.Stop();
            TapAnimation.SetValue(Storyboard.TargetNameProperty,"myImage");
            TapAnimation.Begin();

Questo approccio è ancora più utile quando si genera automaticamente il nuovo nome di destinazione a partire dal controllo che ha attivato l'evento, come nell'esempio seguente:


  private void someImages_PointerPressed(object sender, PointerRoutedEventArgs e)
        {
            TapImage.Stop();
            TapImage.SetValue(Storyboard.TargetNameProperty, (sender as Image).Name);
            TapImage.Begin();
        }

In questo caso, l'oggetto Image toccato dall'utente crea l'evento e noi usiamo il suo nome per la destinazione. Se tutte le immagini nella pagina generano lo stesso evento quando vengono toccate, saranno tutte animate con lo stesso storyboard. Quindi, nell'esempio del tastierino numerico, dovremo creare un solo storyboard per animare tutti i tasti.

Nota  È probabile che tu non conosca la tastiera as: esegue un cast del mittente per trasformarlo in Image.

Più pulsanti, un unico gestore eventi

Nel caso di un'app con più pulsanti simili è opportuno avere un unico gestore eventi master, invece di un gestore eventi per ciascun pulsante. Ogni pulsante può usare lo stesso evento Click, ma è necessario differenziare in qualche modo il codice dei vari pulsanti: questa è la situazione ideale in cui usare i tags.

Come in iOS, ogni controllo o oggetto può avere un tag, ovvero un valore che consente di identificarlo in modo univoco. Ad esempio, tornando al nostro tastierino numerico, potremmo definire i pulsanti come in questo codice XAML: da notare come i pulsanti siano praticamente identici e differiscano solo nel valore del tag.


	<Button Content="1" HorizontalAlignment="Left" Margin="446,78,0,0" VerticalAlignment="Top" Width="120" Height="120" FontSize="48" FontWeight="Bold" Click="Button_Click" Tag="1">
    		<Button.Background>
    			<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    				<GradientStop Color="Black"/>
    				<GradientStop Color="#FF838383" Offset="1"/>
    			</LinearGradientBrush>
    		</Button.Background>
    	</Button>
        <Button Content="2" HorizontalAlignment="Left" Margin="446,543,0,0" VerticalAlignment="Top" Width="460" Height="120" FontSize="48" FontWeight="Bold" Click="Button_Click" Tag="2">
    		<Button.Background>
    			<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    				<GradientStop Color="Black"/>
    				<GradientStop Color="#FF838383" Offset="1"/>
    			</LinearGradientBrush>
    		</Button.Background>
    	</Button>
        <Button Content="3" HorizontalAlignment="Left" Margin="446,393,0,0" VerticalAlignment="Top" Width="120" Height="120" FontSize="48" FontWeight="Bold" Click="Button_Click" Tag="3">
    		<Button.Background>
    			<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
    				<GradientStop Color="Black"/>
    				<GradientStop Color="#FF838383" Offset="1"/>
    			</LinearGradientBrush>
    		</Button.Background>
    	</Button>

Tutti i pulsanti puntano allo stesso gestore eventi, Button_Click. Ecco come leggere il valore del tag e come reagire in modo appropriato all'interno del gestore:


        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var tag = (sender as Button).Tag;

            int t = Convert.ToInt16(tag);

            switch (t)
            {
                case 0: break;
                case 1: break;
                case 2: break;
                default: break;
            }
        }

Argomenti correlati

Utilizzo di animazioni a livello di programmazione
Introduzione: Animazione
Come creare interfacce utente con XAML ed Expression Blend
Animazioni con storyboard

 

 

Mostra:
© 2014 Microsoft