问题
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!
回答1:
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:
- Set the
Button.Contentto be aGridwith both of the images placed inside (thus, overlaying each other). - Set the
Opacityon theImageyou want to be initially visible to 1.0 and 0.0 on theImageto be initially hidden. - Animate the
Opacityusing aDoubleAnimationrather than anObjectAnimation- 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.
来源:https://stackoverflow.com/questions/2783619/how-do-i-animate-image-content-in-wpf