WPF 淡出动画 - 不能再改变不透明度
WPF Fade Out Animation - Can't Change Opacity Any More
我有一个 WPF window,带有用于向用户发送消息的标签控件。几秒钟后,我希望消息消失。为此,我创建了一个 DispatcherTimer
和一个故事板。 (计时器延迟 5 秒,然后 tick 事件触发,消息消失。)它成功消失,但下一条消息的不透明度仍设置为 0。(因此用户看不到它。)显然,我试过了将不透明度设置回 1,但无一例外地失败了。 (也就是说,我可以毫无问题地跨过那行代码,但执行后不透明度仍然为 0。) 谁能告诉我我做错了什么?下面是来自测试项目的一些代码,其中只有一个标签控件、一个用于设置标签内容和淡入淡出动画的按钮,以及一个用于尝试重置不透明度的按钮。
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;
}
默认情况下,动画的 FillBehavior
设置为 HoldEnd
,这意味着动画保持目标 属性 的最终值。如果稍后要重置该值,则需要删除动画,或者将 FillBehavior 设置为 Stop
。然后您可以为动画的 Completed
事件添加处理程序以手动保留最终值。
另请注意,您不需要计时器来延迟动画的开始。您可以改为设置其 BeginTime
属性。
最后,不需要情节提要来为单个 属性 制作动画。您可以改为调用 UIElement.BeginAnimation
。
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;
}
是动画"fill behavior"的缘故。它有效地保持动画后的值不放手,防止它被更新。
这是一个简单的修复,将填充行为更改为停止并添加一个事件处理程序以在动画后将不透明度值更改为 0(否则它将返回到 1)
animation.FillBehavior = FillBehavior.Stop;
animation.Completed += delegate
{
lblTest.Opacity = 0;
};
我已经用你的代码测试过它并且有效。
本
我有一个 WPF window,带有用于向用户发送消息的标签控件。几秒钟后,我希望消息消失。为此,我创建了一个 DispatcherTimer
和一个故事板。 (计时器延迟 5 秒,然后 tick 事件触发,消息消失。)它成功消失,但下一条消息的不透明度仍设置为 0。(因此用户看不到它。)显然,我试过了将不透明度设置回 1,但无一例外地失败了。 (也就是说,我可以毫无问题地跨过那行代码,但执行后不透明度仍然为 0。) 谁能告诉我我做错了什么?下面是来自测试项目的一些代码,其中只有一个标签控件、一个用于设置标签内容和淡入淡出动画的按钮,以及一个用于尝试重置不透明度的按钮。
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;
}
默认情况下,动画的 FillBehavior
设置为 HoldEnd
,这意味着动画保持目标 属性 的最终值。如果稍后要重置该值,则需要删除动画,或者将 FillBehavior 设置为 Stop
。然后您可以为动画的 Completed
事件添加处理程序以手动保留最终值。
另请注意,您不需要计时器来延迟动画的开始。您可以改为设置其 BeginTime
属性。
最后,不需要情节提要来为单个 属性 制作动画。您可以改为调用 UIElement.BeginAnimation
。
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;
}
是动画"fill behavior"的缘故。它有效地保持动画后的值不放手,防止它被更新。
这是一个简单的修复,将填充行为更改为停止并添加一个事件处理程序以在动画后将不透明度值更改为 0(否则它将返回到 1)
animation.FillBehavior = FillBehavior.Stop;
animation.Completed += delegate
{
lblTest.Opacity = 0;
};
我已经用你的代码测试过它并且有效。
本