问题
I want to stop WPF StoryBoard after property of control IsAnimating is changed to false, but I need to stop animation not instantly, but first complete currently running animation cycle and then stop it (I'm using this XAML now, but it stops my animation instantly):
<UserControl x:Class="App.Controls.ProgressCircle"
x:Name="me"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" >
<Ellipse Name="Circle" Width="30" Height="30" Fill="Green" >
<Ellipse.Style>
<Style>
<Style.Resources>
<Storyboard x:Key="Pulsing">
<DoubleAnimation From="30.0" To="0.0" Duration="0:0:1" AutoReverse="True" RepeatBehavior="Forever"
Storyboard.TargetProperty="Width" />
<DoubleAnimation From="30.0" To="0.0" Duration="0:0:1" AutoReverse="True" RepeatBehavior="Forever"
Storyboard.TargetProperty="Height" />
</Storyboard>
</Style.Resources>
<Style.Triggers>
<DataTrigger Binding="{Binding IsAnimating, ElementName=me}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Name="Pulsing" Storyboard="{StaticResource Pulsing}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="Pulsing" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Style>
</Ellipse>
</UserControl>
回答1:
A "quick and dirty" solution would be to start a new animation in the DataTrigger.ExitActions that animates the height and width properties to the values they had before the whole animation was started. This could look like this:
<Style.Triggers>
<DataTrigger Binding="{Binding IsAnimating, ElementName=me}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Name="Pulsing" Storyboard="{StaticResource Pulsing}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:1"
Storyboard.TargetProperty="Height" />
<DoubleAnimation Duration="0:0:1"
Storyboard.TargetProperty="Width" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
The important thing is that if you do not set the the To value on an animation, then the target value will be the one that the dependency property previously had (the local value of 30.0 in this case). You do not have to stop the 'Pulsing' storyboard in this case because this is automatically done when you start a new storyboard that animates the same dependency properties.
Obviously, this is not the optimal solution as you do not integrate the current status of the Pulsing animation (i.e. at which point in time it was when IsAnimating is set to false). As far as I know, there is no built-in functionality in WPF to achieve this kind of functionality, but it might be possible to implement a custom ConstrallableStoryboardAction that respects all these information and that can be set in the DataTrigger.ExitActions instead. It might also be worth your while to check some of Animation How-To topics in the MSDN library.
来源:https://stackoverflow.com/questions/30395106/stop-storyboard-after-currently-running-animation-is-completed