The animation hardly stops and the image resets its position but I want the animation to finish to the next full 360°.
Any ideas on that?
The XAML code:
<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>
The final solution except the fact that it has to be put into a UserControl to make it more generic (also see @Sheridans post and my comment below):
<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>
Code behind:
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();
}
}
}
I don't know of any way to do this in XAML, but with code, there is a
Timeline.Completed
Event that you can use. If you attach a handler to yourStoryboard
, then it will get called when it is finished and you can do whatever you want:In code:
For further help, please see the example in the linked page on MSDN.