如何停止仅在XAML中组成的WPF故事板

6
我有一个在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()停止动画... 它没有任何作用。
我已经查看了这两篇文章,但它们并不适用: Post1 Post2 我能够进入未加载方法,但调用Stop()不能停止动画。据我所知,可能与对storyboard的Begin()调用有关。有一个带有isControlable参数的重载。然而,由于动画完全在XAML中,我不知道如何影响它。
2个回答

12

看起来我遇到了两个不同的问题:

首先,在.NET 3.5中,Storyboard动画可能会泄漏未管理的内存(糟糕):链接链接

由于我不能将目标更新为.NET 4.0,所以我使用了链接中描述的补丁,它已经停止了泄漏。

其次,我成功地连接到了我的UserControl的Unloaded事件,当它所在的窗口关闭时,该事件被调用。我看到其他人在处理这个事件时遇到了问题,但对我来说似乎可以正常工作。停止通过XAML启动的动画(重复行为为“Forever”)的唯一方法是:

storyboard.Begin(this, true);
storyboard.Stop(this);

这个操作会停止动画并允许垃圾回收机制进行清理。


2
谢谢,我一直在寻找停止“永远”动画的方法,但仅仅调用Stop(this)并不能实现。将“true”添加到Start(this)方法中就解决了问题。 - Björn
这个Begin方法有12个重载,其非显式的API设计让我感到困惑。默认值应该是可控的,因为动画本质上是动态的,并且使用纯XAML方法实现相当困难。 - Alois Kraus

1

我已经检查了这两个,但它们并不适用。我能够进入未加载的方法,但调用Stop()不会停止动画。据我所知,可能与对Storyboard的Begin()调用有关。有一个具有isControlable参数的重载。然而,由于动画完全在XAML中,我不确定如何影响它。 - BabaBooey
你为什么没有把那个加到问题里?现在请添加。 - Emond
不行啊...这个混蛋就是一直在运行。为什么它不能好好地听取自己的Stop()方法呢?! :) - BabaBooey
顺便问一下:你怎么知道它一直运行并导致内存泄漏呢? - Emond

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接