Creare un'animazione di fade tra le pagine di una Navigation Application

di Marco Leoncini, in Silverlight 3.0,

La versione 3.0 di Silverlight introduce una nuova tipologia di applicazione chiamato: Navigation Application. Questo nuovo modello permette di creare rapidamente un'applicazione composta di più pagine e di mantenere l'history del browser aggiornata navigando tra una pagina e l'altra.

Il passaggio tra una pagina e l'altra è però visivamente brusco, il contenuto precedente viene semplicemente sostituito con il contenuto della nuova pagina, e questo comportamento è poco adatto ad un'applicazione che punta ad avere un forte impatto dal punto di vista visivo. Per migliorare l'impatto estetico, possiamo aggiungere un effetto di "fade in" e "fade out" tra le pagine estendendo la classe Frame (System.Windows.Navigation).

Creiamo quindi una nuova classe chiamata FadeFrame, che erediti direttamente dal tipo Frame.

C#
public class FadeFrame : Frame
{
    private ContentPresenter _partContent;
    private ContentPresenter _partStaleContent;
    public FadeFrame(): base()
    {
        DefaultStyleKey = typeof(FadeFrame);
    }
}

Nel costruttore della classe impostiamo la proprietà DefaultStyleKey così da utilizzare la nuova template che collocheremo nella cartella chiamata Themes.

XAML
<Style  TargetType="local:FadeFrame">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:FadeFrame">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                    <Grid>
                        <ContentPresenter x:Name="part_content" 
                                          Cursor="{TemplateBinding Cursor}"
                                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                        <ContentPresenter x:Name="part_stalecontent"
                                          Opacity="0"
                                          Cursor="{TemplateBinding Cursor}"   
                                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>     
</Style>

Nella nuova Template inseriamo due ContentPresenter, uno dei quali visualizza la pagina corrente, mentre l'altro visualizza la pagina precedente, ed è animando l'Opacity di questi elementi che creeremo l'effetto di fade.

Torniamo nella classe FadeFrame ed eseguiamo l'override del metodo OnApplyTemplate, nel quale recuperiamo il riferimento ai due ContentPresenter definiti nella Template.

C#
public override void OnApplyTemplate()
{
    base.OnApplyTemplate();
    //recupero le parti utilizzate per mostare il nuovo ed il vecchio contenuto
    _partContent = (ContentPresenter)this.GetTemplateChild("part_content");
    _partStaleContent =(ContentPresenter) this.GetTemplateChild("part_stalecontent");
}

Infine eseguiamo l'override del metodo OnContentChanged, dove impostiamo il contenuto dei due ContentPresenter e ne animiamo l'opacità.

C#
protected override void OnContentChanged(object oldContent, object newContent)
{
    //imposto il contenuto per ogni ContentPresenter
    _partContent.Content = newContent;
    _partStaleContent.Content = oldContent;

    //creo  un nuovo StoryBoard
    Storyboard _storyBoard = new Storyboard();

    //credo le due animazioni e imposto i parametri per creare l'effetto di fade
    DoubleAnimation _contentAnimation = new DoubleAnimation();
    DoubleAnimation _staleContentAnimation = new DoubleAnimation();

    _contentAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(500D));
    _contentAnimation.From = 0;
    _contentAnimation.To = 1;

    _staleContentAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(500D));
    _staleContentAnimation.From = 1;
    _staleContentAnimation.To = 0;

    Storyboard.SetTarget(_contentAnimation, _partContent);
    Storyboard.SetTargetProperty(_contentAnimation, new PropertyPath("(UIElement.Opacity)"));

    Storyboard.SetTarget(_staleContentAnimation, _partStaleContent);
    Storyboard.SetTargetProperty(_staleContentAnimation, new PropertyPath("(UIElement.Opacity)"));

    //imposto lo storyboard e lo esegue
    _storyBoard.Children.Add(_contentAnimation);
    _storyBoard.Children.Add(_staleContentAnimation);
    _storyBoard.Begin();

}

Per utilizzare il nuovo controllo è sufficiente sostituirlo al tradizionale Frame e dichiarare il namespace che lo contiene.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi