WPF Text Fade out-then-in effect WPF Text Fade out-then-in effect wpf wpf

WPF Text Fade out-then-in effect


I'm with frances1983 on this. What I would do is make a new UserControl that actually handles the old and new text seamlessly with the fades.

I'm doing something similar with a label I want to only display for a couple seconds and then disappear. Here's what I've done:

<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 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 could easily modify this sample into a UserControl. Just change the fade out on the Visibility == Hidden, add a storyboard that does the opposite for the Visibility == Visible,and change the text and reset the visibility inside the Tick handler.

Hope this helps!


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

To use (after setting xmlns:l to the correct namespace:

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

The code (this is proof-of-concept code, without error handeling an is not production ready).

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


The best solution for this task would be to use a "Transition Presenter". Transition presenter is a container for your control (can be TextBlock or whatever else) which reacts to the change of the content by applying the assigned transition. You can select one of the pre-defined transitions or create your own (using XAML). Usually transition presenter uses a data template to display the bound data. Most basic 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 libraries with source code that implement transition presenter: