Reputation: 701
I have a really basic user control with a button that has an image. I want to animate the image of the button, by changing it to a different image.
<UserControl.Resources>
<Image x:Key="GlyphDefault" Source="pack://application:,,,/X;component/images/Glyphs_Default.png" Height="8" Width="8" />
<Image x:Key="GlyphClicked" Source="pack://application:,,,/X;component/images/Glyphs_Click.png" Height="8" Width="8" />
</UserControl.Resources>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="MouseStates">
<VisualState Name="MouseHover" >
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="GlyphButton"
Storyboard.TargetProperty="Content"
Duration="0:0:1" >
<ObjectAnimationUsingKeyFrames.KeyFrames>
<DiscreteObjectKeyFrame KeyTime="0:0:1">
<DiscreteObjectKeyFrame.Value="{StaticResource GlyphClicked}" />
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames.KeyFrames>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState Name="MouseNotHover" >
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Button x:Name="GlyphButton"
MouseLeave="GlyphButton_MouseLeave"
MouseEnter="GlyphButton_MouseEnter"
Content="{StaticResource GlyphDefault}"
/>
</Grid>
Unfortunately, when I run this, and hover over the button I get "Freezable cannot be frozen" exception (the Mouse event handlers change the states). It appears that it's trying to freeze the current image, but can't for some reason.
I've tried doing it without using a static resource (just putting the Image inline) too, but same error. Oddly, I can find very little documentation or blogs about doing animations on the Content property. I'd have to imagine this would be a common scenario. Any ideas as to what I'm doing wrong?
I greatly appreciate your help on this!
Upvotes: 0
Views: 4607
Reputation: 15247
This is probably not the best (or easiest) way to go about this. The Content
property is definitely not what the WPF designers had in mind for animations. Here is how I would do this instead:
Button.Content
to be a Grid
with both of the images placed inside (thus, overlaying each other).Opacity
on the Image
you want to be initially visible to 1.0 and 0.0 on the Image
to be initially hidden.Opacity
using a DoubleAnimation
rather than an ObjectAnimation
- you can switch the images by animating one's opacity down to 0.0 while simultaneously bringing the other one up to 1.0. Furthermore, depending on the duration, this will gave you a nice fading transition.Upvotes: 3