如何停止仅用 XAML 编写的 WPF 故事板
我在 XAML 中定义了一个动画(作为 UserControl),它基本上每秒在两个图像之间切换:
<UserControl x:Class="KaleidoscopeApplication.Controls.RemoteAnimation"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Loaded="RemoteAnimation_Loaded"
Unloaded="RemoteAnimation_Unloaded">
<Grid Canvas.Left="500" Canvas.Top="84">
<Grid.Triggers>
<EventTrigger RoutedEvent="Grid.Loaded">
<BeginStoryboard>
<Storyboard x:Name="storyboard" RepeatBehavior="Forever">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="remote2" BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0:0:1">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:2">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Image Name="remote1" Source="/Resources/Elements/Images/341.png"/>
<Image Name="remote2" Source="/Resources/Elements/Images/342.png"/>
</Grid>
</UserControl>
因此它可以在窗口中使用:
<!-- Remote -->
<uControl:RemoteAnimation
x:Name="remoteAnimation"
Canvas.Left="316" Canvas.Top="156" Height="246" Width="121" />
我的问题是,当包含动画的窗口关闭时,它会继续运行并导致泄漏。我无法通过 RemoteAnimation_Unloaded() 和 Storyboard.Stop() 停止动画...它不起作用。
我已经检查了这两篇文章,但它们并不适用:
我能够进入卸载的方法,但调用 Stop() 不会停止动画片。根据我的理解,这可能是调用故事板的 Begin() 的问题。 isControlable 参数存在重载。但是,由于动画完全采用 XAML,我不确定如何影响它。
I have a animation defined in XAML (as a UserControl) that essentially switches between two images every second:
<UserControl x:Class="KaleidoscopeApplication.Controls.RemoteAnimation"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Loaded="RemoteAnimation_Loaded"
Unloaded="RemoteAnimation_Unloaded">
<Grid Canvas.Left="500" Canvas.Top="84">
<Grid.Triggers>
<EventTrigger RoutedEvent="Grid.Loaded">
<BeginStoryboard>
<Storyboard x:Name="storyboard" RepeatBehavior="Forever">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="remote2" BeginTime="00:00:00" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0:0:1">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:2">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Image Name="remote1" Source="/Resources/Elements/Images/341.png"/>
<Image Name="remote2" Source="/Resources/Elements/Images/342.png"/>
</Grid>
</UserControl>
It can be used in a window thusly:
<!-- Remote -->
<uControl:RemoteAnimation
x:Name="remoteAnimation"
Canvas.Left="316" Canvas.Top="156" Height="246" Width="121" />
My problem is that when the window containing the animation closes, it keeps on running and causes a leak. I'm not able to stop the animation via RemoteAnimation_Unloaded() with storyboard.Stop()... it doesn't do jack.
I've checked out both of those posts, but they don't apply:
I am able to get into the unloaded method, but calling Stop() does not stop the animation. From my understanding, it may be an issue with a call to Begin() for the storyboard. There is an overload with an isControlable parameter. However, since the animation is completely in XAML, I'm not sure how to affect this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
请阅读这两篇文章:
未触发卸载事件
处置 UserControls
Please read these two posts:
Unloaded event not triggered
Disposing UserControls
看起来我遇到了两个不同的问题:
首先,在 .NET 3.5 中,故事板动画可能会泄漏非托管内存(呃):
链接,链接
因为我无法选择将目标更新为 .NET 4.0,我使用了链接中描述的补丁,它已经阻止了泄漏。
其次,我能够成功连接到我的 UserControl 的 Unloaded 事件,该事件在包含窗口关闭时被调用。我看到其他人在正确触发此事件时遇到了麻烦,但它似乎对我有用。停止动画(通过 XAML 使用“Forever”的
RepeatBehavior
启动)的唯一方法是:这将停止动画并允许 GC 收集它。
Looks like I was running into two separate issues:
First off, in .NET 3.5, storyboard animations can leak unmanaged memory (ugh):
Link, Link
Since I don't have the option to update my targets to .NET 4.0, I used the patch described in the links and it has stopped the leak.
Second, I was able to successfully hook up to my UserControl's Unloaded event, which is called when it's containing window is closed. I see others have had trouble with this event firing properly, but it seems to work for me. The only way to stop the animation (which was started via XAML with
RepeatBehavior
of "Forever") is:This stops the animation and allows the GC to collect it.