【问题标题】:WPF animation problem when using Storyboard from code从代码中使用 Storyboard 时出现 WPF 动画问题
【发布时间】:2010-12-31 10:00:17
【问题描述】:

我正在制作一个包含信息的扁平方形瓷砖的 3D 旋转木马。我正在为这个轮播设置动画,使其在一个人按下下一个和上一个按钮时旋转。

我已经通过在应用于轮播的 RotateTransform3D 的 Rotation 属性上使用 BeginAnimation 来使其工作,但我似乎无法使相同动画的 Storyboard 版本工作。我需要 Storyboard 版本的原因是 HandOffBehavior.Compose 参数,因为没有它,多次单击我的下一个和上一个按钮会导致轮播不对齐。

这是情节提要的代码:

RotateTransform3D tempTransform = (RotateTransform3D)wheel.Transform;
AxisAngleRotation3D rotation = (AxisAngleRotation3D)tempTransform.Rotation;

Storyboard storyboard = new Storyboard();            
DoubleAnimation animation = new DoubleAnimation();
animation.By = defaultAngle;
animation.Duration = TimeSpan.FromSeconds(.5);

Storyboard.SetTarget(animation, rotation);
Storyboard.SetTargetProperty(animation, new PropertyPath("Angle"));
storyboard.Children.Add(animation);

storyboard.Duration = animation.Duration;            
storyboard.Begin(new FrameworkContentElement(), HandoffBehavior.Compose);

由于某种原因,这段代码完全没有结果。我遵循了我必须信中的例子,所以我很沮丧。任何帮助是极大的赞赏。如果我可以复制 HandOffBehavior.Compose,我也完全愿意使用 BeginAnimation。

【问题讨论】:

  • 我认为你应该接受奥利弗的回答。如果将Storyboard.SetTarget(animation, rotation) 替换为Storyboard.SetTargetName(animation, "rotation"),它将起作用。另见this

标签: wpf 3d


【解决方案1】:

我的经验来自 2D 动画,但我猜问题是一样的。

出于某些愚蠢的原因(可能与对 XAML 的不健康关注有关),Storyboards 只能通过按名称查找 Freezable 对象来制作动画。 (参见Storyboards Overview 中的示例。)因此,尽管您在调用 Storyboard.SetTarget(animation, rotation) 时提供了对“旋转”对象的引用,但故事板只想记住并使用它没有的名称。

解决办法是:

  • 围绕将控制转换的元素创建一个命名范围。
  • 为每个正在动画的 Freezable 对象调用 RegisterName()。
  • 将元素传递给 Storyboard.Begin()

这会使您的代码看起来像这样(未经测试):

FrameworkContentElement element = new FrameworkContentElement();
NameScope.SetNameScope(element, new NameScope());

RotateTransform3D tempTransform = (RotateTransform3D)wheel.Transform;
AxisAngleRotation3D rotation = (AxisAngleRotation3D)tempTransform.Rotation;
element.RegisterName("rotation", rotation);

Storyboard storyboard = new Storyboard();            
DoubleAnimation animation = new DoubleAnimation();
animation.By = defaultAngle;
animation.Duration = TimeSpan.FromSeconds(.5);

Storyboard.SetTarget(animation, rotation);
Storyboard.SetTargetProperty(animation, new PropertyPath("Angle"));
storyboard.Children.Add(animation);

storyboard.Duration = animation.Duration;            
storyboard.Begin(element, HandoffBehavior.Compose);

在 XAML 中这些都不是必需的,因为您的对象是自动注册的。

编辑:但后来我发现你可以通过完全省略情节提要来简化事情:

var T = new TranslateTransform(40, 0);
Duration duration = new Duration(new TimeSpan(0, 0, 0, 1, 0);
DoubleAnimation anim = new DoubleAnimation(30, duration);
T.BeginAnimation(TranslateTransform.YProperty, anim);

【讨论】:

  • 用 Storyboard.SetTargetName(animation, "rotation") 替换 Storyboard.SetTarget(animation, rotation)。
猜你喜欢
  • 2011-01-07
  • 1970-01-01
  • 2022-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-21
  • 1970-01-01
相关资源
最近更新 更多