Text WPF Fade out-then-in effect

I am trying to use WPF animation to create an effect where when the data in the text property changes, the text disappears, then again .. or preferably a suitable crossfade.

I successfully got half of this work, the code below responds to the event with the changed text, immediately makes the text invisible, and then disappears within 3 seconds.

To fade the text as easily, I just change the From and To properties of the tag. BUT - the problem is that the text on the screen changes immediately. This is usually absolutely necessary, but in this case I want the OLD text to disappear, then the new text to disappear.

Is there any clever trick for this in WPF animation?

Current half-closed 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> 
+6
text animation wpf
source share
4 answers

I am with frances1983 on this. I would make a new UserControl that actually processes the old and new text unchanged.

I do something similar with a label that I want to show only a couple of seconds and then disappear. Here is what I did:

 <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> 

And then in the code where the label text changes:

 //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(); 

You can easily change this pattern in UserControl. Just change the fade to Visibility == Hidden, add a storyboard that does the opposite for Visibility == Visible, and change the text and reset visibility inside the Tick handler.

Hope this helps!

+3
source share

Here is an implementation that automatically makes the value fade-out, switch disappears in

To use (after installing xmlns: l in the correct namespace:

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

Code (this is the code of the evidence-based concept, without error handling, not ready for production).

 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(); } } 
+2
source share

The best solution for this task would be to use the "Transition Presenter". A transition presenter is a container for your control (maybe a TextBlock or something else) that responds to content changes by applying a designated transition. You can choose one of the predefined transitions or create your own (using XAML). Typically, a broadcast guide uses a data template to display related data. The simplest example would look like this:

 <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> 

Here are two source code libraries that implement the transition presentation:

+1
source share

I do not think this is possible in a XAML solution. TextBlock does not know about the "old" and "new" text, only Text.

The way I do this is to create a user control derived from a TextBlock, and do the following on a TargetUpdated-event:

  • Challenge the storyboard "Fade out"
  • Change text
  • Call the "Fade in" storyboard.

Good luck :)

-one
source share

All Articles