2013-12-10 98 views
0

动画几乎不会停止并且图像重置其位置,但我希望动画完成到下一个完整的360°。WPF:如何使用DataTrigger平滑停止旋转动画

有关于此的任何想法?

的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> 

最终的解决方案除了一个事实,即它必须放入用户控件,使其更通用的(见@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(); 
     } 
    } 
} 

回答

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上的链接页面。

+0

你的提示让我走向正确的方向。此外,我使用了下面的堆栈,因为我必须将Storyboard放入才能使用Completed事件:http://stackoverflow.com/questions/4434746/xaml-heartbeat-animation-how-to-ensure -Heart-次-AT-最少两次。我会将我的最终解决方案放入我的问题中,并将您的帖子标记为答案。 – timmkrause

+0

感谢您使用您的解决方案回来更新此问题。 – Sheridan