I have a WPF window with a label control used for messages to the user. After a few seconds, I want the message to fade away. I have created a DispatcherTimer
and a storyboard to do this. (The timer delays for 5 seconds and then the tick event fires and the message fades away.) It successfully fades away, but the next message still has its opacity set to 0. (So the user cannot see it.) Obviously, I tried setting the opacity back to 1, but that fails with no exceptions. (that is, I can step over that line of code with no problems, but the opacity is still 0 after executing it.) Can anyone tell me what I'm doing wrong? Here is some code from a test project with just a label control, a button to set the label's content and the fade animation, and a button to attempt to reset the opacity.
XAML:
<Window x:Class="WpfTestApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="100" Width="525">
<Grid>
<StackPanel x:Name="stkHeaderBar" Grid.Row="0" Background="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" Orientation="Horizontal" FlowDirection="RightToLeft">
<Label x:Name="lblTest" Content="lblTest"/>
<Button x:Name="btnChangeLabel" Content="ChangeLabel" Click="btnChangeLabel_Click"/>
<Button x:Name="btnResetOpacity" Content="Reset Opacity" Click="btnResetOpacity_Click"/>
</StackPanel>
</Grid>
</Window>
C#:
private void btnChangeLabel_Click(object sender, RoutedEventArgs e)
{
lblTest.Content = "Testing1...Testing2...Testing3";
lblTest.Opacity = 1;
// Create a storyboard to contain the animations.
Storyboard storyboard = new Storyboard();
TimeSpan duration = new TimeSpan(0, 0, 2);
// Create a DoubleAnimation to fade the not selected option control
DoubleAnimation animation = new DoubleAnimation();
animation.From = 1.0;
animation.To = 0.0;
animation.Duration = new Duration(duration);
// Configure the animation to target de property Opacity
Storyboard.SetTargetName(animation, lblTest.Name);
Storyboard.SetTargetProperty(animation, new PropertyPath(Control.OpacityProperty));
// Add the animation to the storyboard
storyboard.Children.Add(animation);
// Begin the storyboard
storyboard.Begin(this);
}
private void btnResetOpacity_Click(object sender, RoutedEventArgs e)
{
lblTest.Opacity = 1;
}
By default, an animation's FillBehavior
is set to HoldEnd
, which means that the animation holds the final value of the target property. If you want to reset the value later, you either need to remove the animation, or you set the FillBehavior to Stop
. You could then add a handler for the animation's Completed
event to keep the final value manually.
Note also that you don't need a timer to delay the start of the animation. You may set its BeginTime
property instead.
Finally, no Storyboard is needed to animate a single property. You could call UIElement.BeginAnimation
instead.
private void btnChangeLabel_Click(object sender, RoutedEventArgs e)
{
var animation = new DoubleAnimation
{
To = 0,
BeginTime = TimeSpan.FromSeconds(5),
Duration = TimeSpan.FromSeconds(2),
FillBehavior = FillBehavior.Stop
};
animation.Completed += (s, a) => lblTest.Opacity = 0;
lblTest.BeginAnimation(UIElement.OpacityProperty, animation);
}
private void btnResetOpacity_Click(object sender, RoutedEventArgs e)
{
lblTest.Opacity = 1;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With