(转载)解决WPF动画属性锁死问题

时间:2022-04-01 05:46:31

此文来自: 马开东博客 转载请注明出处 网址:http://www.makaidong.com

一般锁死问题都是出在后台代码写的动画中,以下为转载的解决方案!

方法一:将动画的 FillBehavior 属性设置为 Stop:

storyboard.FillBehavior = FillBehavior.Stop;

通过将FillBehavior设置为Stop,即通知动画在到达其活动期末尾后停止

影响其目标关联属性。虽然达到了目的,但必须等待动画结束时才会生效,且更关键的是之前被storyboard修改过的所有关联属性值此时都被还原成了初始值。因此,此方法只适合用于制作类似网页中的导航菜单按钮:当鼠标悬停在菜单上时,菜单图形按钮执行一段华丽的变化动画;当鼠标移开后即变回为初始图片。

方法二:移除整个动画板(Storyboard)。此方法必须通过类似

Leader.BeginStoryboard(storyboard, HandoffBehavior.SnapshotAndReplace, true);或

storyboard.Begin(Leader, HandoffBehavior.SnapshotAndReplace, true);

这两种方式启动动画,然后在需要解锁时通过

storyboard.Remove(Leader); storyboard = null; 通知动画板动画停止影响名为Leader对象的目标关联属性,并移除storyboard。需要特别注意的是①必须将动画的IsControllable参数设置为true;②HandoffBehavior最好设置为SnapshotAndReplace,此枚举的作用是:新动画将替换它们所应用到的关联属性上的任何现有动画。

方法三:从单个关联属性移除动画。同样的以精灵角色朝向为例,如果该属性已被Storyboard锁定,那么如果此时需要对其值进行更改,我们可以通过类似:

Leader.BeginAnimation(QXSpirit.DirectionProperty, null);或

Leader.ApplyAnimationClock(QXSpirit.DirectionProperty, null);

这两种方法来禁止关联到Leader的动画继续影响Leader的DirectionProperty关联属性(此方法对于非动画板动画

也同样有效)。接着后面我们就可以轻松的通过Leader.Direction = 0 为精灵的朝向属性进行赋值并在画面中得到体现。

以上三种解决方案 在WPF中灵活的配合storyboard.Children.Clear();使用几乎可以应付任何关于Storyboard锁死关联属性的问题;但是在Silverlight 中却往往不尽如人意。毕竟只是WPF的子集,在功能与方法上有着太少的支持。因此,我拓展了以下两种解决方案 ,更重要的,它们均为WPF/Silverlight 通用的且药到病除的终极策略。

方法四:可以通过每次运行新的动画时先暂停之前的动画(注意,是暂停(Pause)而不是停止(Stop)),例如storyboard.Pause(Leader);然后再创建一个新的动画板storyboard = new Storyboard();这样,之前被storyboard修改过的关联属性目标值会被新的storyboard作为起点属性值,从而完美实现关联属性在动画与动画之间的衔接。有些朋友会问那之前的storyboard是否会继续占用内存空间?对于.net的内存回收机制我们无法控知,根据我多方查阅的资料,若您不放心,不妨在创建新的Storyboard前,通过storyboard = null 将之注销掉,在Silverlight 动画中我是这样做的,实践证明此方法确实达到的目的。

方法五:以毒攻毒。既然是Storyboard锁死了我们需要更改的关联属性,那么我们同样可以通过Storyboard动画的形式来赋值更改这些关联属性。此方法乃下下策,缺点是毫无性能而言;优点是万能性:适合一切被Storyboard锁死的关联属性的修改,且无论是在WPF还是Silverlight 中。下面同样以精灵的朝向为例,我们可以通过:

DoubleAnimation doubleAnimation = new DoubleAnimation();

doubleAnimation.To = direction;

doubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(10));

Storyboard.SetTarget(doubleAnimation, spirit);

Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("Direction"));

storyboard.Children.Add(doubleAnimation);

storyboard.Begin();
这样的动画形式对QXSpirit.DirectionProperty关联属性进行强行更改。

本节小结:希望以上5种解锁Storyboard关联属性的解决方案 能对大家的WPF/Silverlight 动画开发有所帮助;同时,如果哪些地方有写得不妥或有错漏的也请大家不吝赐教,我会及时进行修改及更正。