After getting the animation on an image to run
which I got from here: Animate image in a button
I want to be able to switch the animation on and off, depending
on a button click from outside, i.e. from the ViewModel
So I added a new DependencyProperty to the Bahavior (with all those things that are needed here)
public static readonly DependencyProperty IsShakingProperty =
DependencyProperty.Register(IsShakingName,
typeof(bool),
typeof(ShakeBehavior),
new PropertyMetadata(DefaultIsShaking));
I have added a new public property to my ViewModel
public bool IsShaking { get; set; }
But what can I do to switch the animation on and off, depending on the
ViewModel property set to true or false? (I want to control the animation
on a button click)
Here is some of the code of which i think it is relevant
private Timeline CreateAnimationTimeline()
{
DoubleAnimationUsingKeyFrames animation = new DoubleAnimationUsingKeyFrames();
animation.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(0).(1)", UIElement.RenderTransformProperty, RotateTransform.AngleProperty));
int keyFrameCount = 8;
double timeOffsetInSeconds = 0.25;
double totalAnimationLength = keyFrameCount * timeOffsetInSeconds;
double repeatInterval = RepeatInterval;
bool isShaking = IsShaking;
// Can't be less than zero and pointless to be less than total length
if (repeatInterval < totalAnimationLength)
repeatInterval = totalAnimationLength;
animation.Duration = new Duration(TimeSpan.FromSeconds(repeatInterval));
int targetValue = 12;
for (int i = 0; i < keyFrameCount; i++)
animation.KeyFrames.Add(new LinearDoubleKeyFrame(i % 2 == 0 ? targetValue : -targetValue, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(i * timeOffsetInSeconds))));
animation.KeyFrames.Add(new LinearDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(totalAnimationLength))));
return animation;
}
Here is the part of my XAML:
<ListBox.ItemTemplate>
<DataTemplate>
<Button Focusable="False" Command="{Binding ClickToolCommand}" Grid.Row="{Binding Path=Row}" Grid.Column="{Binding Path=Col}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0">
<Image Source="myImage.png" Grid.Row="{Binding Path=Row}" Grid.Column="{Binding Path=Col}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0">
<i:Interaction.Behaviors>
<local:ShakeBehavior RepeatInterval="1" SpeedRatio="3.0" IsShaking="{Binding Path=IsShaking}"/>
</i:Interaction.Behaviors>
</Image>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
Perhaps a DataTrigger can help, as pointed out in other SOs, but I do not have a storyboard inside my XAML, as I have a custom Behavior
Any input highly appreciated!
Firstly, let me repeat what I said in the original post that started this whole thing. Doing a “shaky” image button becomes a whole lot simpler if you just use a custom control. Also, using a shaky image button as “a way to engage a users attention” is a horrible idea that reminds me of 1990’s website design. In addition, there is a small flaw in the implementation you copied, there is no exit action on the trigger that was created. Regardless, here is how to do what you require:
Create an attached property as follows:
Then replace the existing “OnAttach” method with the folllowing:
Then instead of having the shaking trigger based off the visibility of the button, change it to work off your attached property:
Then you use it as follows: