【问题标题】:WPF: How to smoothly stop a rotation animation with the DataTriggerWPF:如何使用 DataTrigger 平滑停止旋转动画
【发布时间】:2013-12-27 22:50:14
【问题描述】:

动画几乎没有停止,图像会重置其位置,但我希望动画完成到下一个完整的 360°。

对此有什么想法吗?

XAML 代码:

<Button
    BorderThickness="0"
    Cursor="Hand"
    Command="{Binding RefreshCommand}">
    <Button.Template>
        <ControlTemplate TargetType="Button">
            <Border>
                <ContentPresenter />
            </Border>
        </ControlTemplate>
    </Button.Template>
    <Image Source="../Resources/RefreshIcon.png">
        <Image.Style>
            <Style>
                <Setter Property="Image.RenderTransform">
                    <Setter.Value>
                        <RotateTransform />
                    </Setter.Value>
                </Setter>
                <Setter Property="Image.RenderTransformOrigin" Value=".5,.5">
                </Setter>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsRefreshing}" Value="True">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard Name="RotationStoryboard">
                                <Storyboard>
                                    <DoubleAnimation
                                        Storyboard.TargetProperty="RenderTransform.Angle"
                                        From="0"
                                        To="360"
                                        Duration="0:0:0.8"
                                        RepeatBehavior="Forever" />
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding IsRefreshing}" Value="False">
                        <DataTrigger.EnterActions>
                            <RemoveStoryboard BeginStoryboardName="RotationStoryboard"/>
                        </DataTrigger.EnterActions>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Image.Style>
    </Image>
</Button>

最终解决方案,除了必须将其放入 UserControl 以使其更通用(另见@Sheridans 帖子和我在下面的评论):

<Button
    BorderThickness="0"
    Cursor="Hand"
    Command="{Binding RefreshCommand}">
    <Button.Template>
        <ControlTemplate TargetType="Button">
            <Border>
                <ContentPresenter />
            </Border>
        </ControlTemplate>
    </Button.Template>
    <Image
        Name="RefreshImage"
        Source="../Resources/RefreshIcon.png"
        RenderTransformOrigin=".5,.5">
        <Image.Resources>
            <Storyboard
                x:Key="RotationStoryboard"
                Completed="RotationStoryboardCompleted">
                <DoubleAnimation
                    Storyboard.Target="{Binding ElementName=RefreshImage}"
                    Storyboard.TargetProperty="RenderTransform.Angle"
                    From="0"
                    To="360"
                    Duration="0:0:1.5">
                    <DoubleAnimation.EasingFunction>
                        <CircleEase EasingMode="EaseInOut"></CircleEase>
                    </DoubleAnimation.EasingFunction>
                </DoubleAnimation>
            </Storyboard>
        </Image.Resources>
        <Image.Style>
            <Style>
                <Setter Property="Image.RenderTransform">
                    <Setter.Value>
                        <RotateTransform />
                    </Setter.Value>
                </Setter>
                <Setter Property="Image.RenderTransformOrigin" Value=".5,.5">
                </Setter>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsRefreshing}" Value="True">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard>
                                <StaticResource ResourceKey="RotationStoryboard"/>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Image.Style>
    </Image>
</Button>

后面的代码:

public partial class SomeView
{
    public SomeView()
    {
        InitializeComponent();
    }

    private void RotationStoryboardCompleted(object sender, EventArgs e)
    {
        var viewModel = (ISomeViewModel)DataContext;
        var storyboard = (Storyboard)((ClockGroup)sender).Timeline;

        if (viewModel.IsRefreshing)
        {
            storyboard.Begin();
        }
    }
}

【问题讨论】:

    标签: wpf xaml animation datatrigger rotatetransform


    【解决方案1】:

    我不知道有什么方法可以在 XAML 中执行此操作,但是通过代码,您可以使用 Timeline.Completed Event。如果您将处理程序附加到您的Storyboard,那么它将在完成后被调用,您可以做任何您想做的事情:

    <BeginStoryboard>
        <Storyboard Name="RotationStoryboard" Completed="StoryboardCompleted">
            <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle" From="0" 
    To="360" Duration="0:0:0.8" />
        </Storyboard>
    </BeginStoryboard>
    

    在代码中:

    private void StoryboardCompleted(object sender, EventArgs e)
    {
        // Restart your Storyboard here each time until you want it to stop.
    }
    

    如需进一步帮助,请参阅 MSDN 上链接页面中的示例。

    【讨论】:

    • 您的提示将我引向正确的方向。此外,我使用了以下堆栈,因为我必须将 Storyboard 放入 才能使用 Completed 事件:stackoverflow.com/questions/4434746/…。我会将我的最终解决方案放入我的问题中,并将您的帖子标记为答案。
    • 感谢您回来用您的解决方案更新此问题。
    猜你喜欢
    • 1970-01-01
    • 2017-03-29
    • 2015-12-26
    • 2015-08-23
    • 1970-01-01
    • 2013-04-17
    • 2013-08-01
    • 1970-01-01
    • 2012-01-29
    相关资源
    最近更新 更多