2009-08-11 19 views
6

Sto provando a utilizzare l'animazione WPF per creare un effetto in cui, quando i dati in una proprietà di testo cambiano, il testo scompare, quindi di nuovo .. o preferibilmente un dissolvenza incrociata corretta .Testo WPF Effetto dissolvenza in uscita

Ho ottenuto con successo metà del funzionamento, il codice riportato di seguito risponde all'evento di testo modificato, rende immediatamente invisibile il testo e lo dissolve in oltre 3 secondi.

Dissolvenza del testo è analogamente semplice, cambio solo le proprietà Da e A del tag. MA - il problema è che il testo sullo schermo cambia immediatamente. Questo di solito è assolutamente necessario, ovviamente, ma in questo caso voglio che il testo OLD si dissolva, quindi il NUOVO testo si dissolva.

C'è qualche trucco intelligente per farlo nell'animazione WPF?

corrente mezzo finito trigger:

<Style TargetType="TextBlock" x:Key="fadeinout"> 
     <Style.Triggers> 
      <EventTrigger RoutedEvent="Binding.TargetUpdated"> 
       <BeginStoryboard> 
        <Storyboard> 
         <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:3" From="0.0" To="1.0" BeginTime="0:0:0" /> 
        </Storyboard> 
       </BeginStoryboard> 
      </EventTrigger> 
     </Style.Triggers> 
    </Style> 

risposta

-1

non credo che questo è forse in una soluzione di XAML-only. TextBlock non conosce il testo "vecchio" e "nuovo", solo il testo.

Il modo in cui vorrei farlo è quello di creare un controllo personalizzato che deriva da TextBlock, e procedere come segue sul TargetUpdated-evento:

  • chiamata 'Fade out' storyboard
  • Modifica testo
  • chiamata 'Fade in' storyboard

Buona fortuna :)

+0

è possibile, è sufficiente utilizzare solo due blocchi di testo – sam

1

La soluzione migliore per questo compito sarebbe di utilizzare un "Presentatore di transizione". Transition presenter è un contenitore per il tuo controllo (può essere TextBlock o qualsiasi altra cosa) che reagisce al cambiamento del contenuto applicando la transizione assegnata. È possibile selezionare una delle transizioni predefinite o crearne di proprie (utilizzando XAML). In genere il presentatore di transizione utilizza un modello di dati per visualizzare i dati associati. La maggior esempio di base sarebbe simile a questa:

<lib:TransitionPresenter Transition="{StaticResource FadeTransition} 
    Content="{Binding MyValue}"> 
    <lib:TransitionPresenter.Resources> 
     <DataTemplate DataType="{x:Type System:string}"> 
      <TextBlock Text={Binding}/> 
     </DataTemplate> 
    </lib:TransitionPresenter.Resources> 
</lib:TransitionPresenter> 

Qui ci sono due librerie con il codice sorgente che implementano presentatore transizione:

3

sto con frances1983 su Questo. Quello che vorrei fare è creare un nuovo UserControl che gestisca il vecchio e il nuovo testo perfettamente con le dissolvenze.

Sto facendo qualcosa di simile con un'etichetta che voglio visualizzare solo per un paio di secondi e poi scomparire. Ecco quello che ho fatto:

<Label Name="lbl" DockPanel.Dock="Bottom" HorizontalAlignment="Center" Visibility="Collapsed"> 
    <Label.Style> 
     <Style TargetType="{x:Type Label}"> 
      <Style.Triggers> 
       <Trigger Property="Visibility" Value="Visible"> 
        <Trigger.EnterActions> 
         <BeginStoryboard> 
          <Storyboard> 
           <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="00:00:00" BeginTime="00:00:00" From="0.0" To="1.0" /> 
           <DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="00:00:03" BeginTime="00:00:02" From="1.0" To="0.0" /> 
          </Storyboard> 
         </BeginStoryboard> 
        </Trigger.EnterActions> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </Label.Style> 
    Display Text 
</Label> 

E poi nel codice in cui l'etichetta modifiche al testo:

//Make the label visible, starting the storyboard. 
lbl.Visibility = Visibility.Visible; 

DispatcherTimer t = new DispatcherTimer(); 
//Set the timer interval to the length of the animation. 
t.Interval = new TimeSpan(0, 0, 5); 
t.Tick += (EventHandler)delegate(object snd, EventArgs ea) 
{ 
    // The animation will be over now, collapse the label. 
    lbl.Visibility = Visibility.Collapsed; 
    // Get rid of the timer. 
    ((DispatcherTimer)snd).Stop(); 
}; 
t.Start(); 

si potrebbe facilmente modificare questo campione in un UserControl.Basta cambiare la dissolvenza in Visibilità == Nascosto, aggiungere uno storyboard che faccia l'opposto per Visibilità == Visibile, e cambiare il testo e ripristinare la visibilità all'interno del gestore di tick.

Spero che questo aiuti!

2

Ecco un'implementazione che automaticamente fare il fade-out, valore interruttore, dissolvenza in

Per usare (dopo aver impostato xmlns: l al namespace corretto:

Label l:AnimatedSwitch.Property="Content" l:AnimatedSwitch.Binding="{Binding SomeProp}"/> 

Il codice (questo è codice proof-of-concept, senza errori di gestione e non è pronto per la produzione)

public class AnimatedSwitch : DependencyObject 
{ 
    // Define the attached properties 

    public static DependencyProperty BindingProperty = 
     DependencyProperty.RegisterAttached("Binding", typeof(object), typeof(AnimatedSwitch), 
     new PropertyMetadata(BindingChanged)); 
    public static DependencyProperty PropertyProperty = 
     DependencyProperty.RegisterAttached("Property", typeof(string), typeof(AnimatedSwitch)); 
    public static object GetBinding(DependencyObject e) 
    { 
     return e.GetValue(BindingProperty); 
    } 
    public static void SetBinding(DependencyObject e, object value) 
    { 
     e.SetValue(BindingProperty, value); 
    } 
    public static string GetProperty(DependencyObject e) 
    { 
     return (string)e.GetValue(PropertyProperty); 
    } 
    public static void SetProperty(DependencyObject e, string value) 
    { 
     e.SetValue(PropertyProperty, value); 
    } 

    // When the value changes do the fadeout-switch-fadein 

    private static void BindingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     Storyboard fadeout = new Storyboard(); 
     var fadeoutAnim = new DoubleAnimation(){To=0,Duration=new Duration(TimeSpan.FromSeconds(0.3))}; 
     Storyboard.SetTarget(fadeoutAnim,d); 
     Storyboard.SetTargetProperty(fadeoutAnim, new PropertyPath("Opacity")); 
     fadeout.Children.Add(fadeoutAnim); 
     fadeout.Completed += (d1, d2) => 
      { 
       d.GetType().GetProperty(GetProperty(d)).SetValue(d, GetBinding(d), null); 

       Storyboard fadein = new Storyboard(); 
       var fadeinAnim = new DoubleAnimation() { To = 1, Duration = new Duration(TimeSpan.FromSeconds(0.3)) }; 
       Storyboard.SetTarget(fadeinAnim, d); 
       Storyboard.SetTargetProperty(fadeinAnim, new PropertyPath("Opacity")); 
       fadein.Children.Add(fadeinAnim); 
       fadein.Begin(); 
      }; 
     fadeout.Begin(); 
    } 
} 
Problemi correlati