C# WPF中动态修改DoubleAnimation的TargetName属性以实现多图片动画的解决方案问询
动态修改DoubleAnimation的TargetName以实现多元素动画
针对你需要在C#后台切换动画目标元素(9张图片)的需求,这里有两种实用的解决方案,你可以根据场景选择:
方案一:修改现有Storyboard中动画的TargetName
如果你想复用XAML中已定义的动画逻辑,只需要在后台遍历Storyboard的动画元素,动态更新TargetName即可:
首先,调整你的AnimateFood方法:
public void AnimateFood(string targetElementName) { // 直接使用页面中定义的Storyboard实例 var storyboard = MyAnimationBoard1; // 遍历所有动画,修改TargetName(如果只需要播放单个动画,可移除其他冗余动画) foreach (var child in storyboard.Children.ToList()) { if (child is DoubleAnimationUsingKeyFrames keyFrameAnim) { // 更新目标元素名称 Storyboard.SetTargetName(keyFrameAnim, targetElementName); // 可选:如果不需要多动画同时播放,保留当前动画即可 // storyboard.Children.RemoveAll(c => c != keyFrameAnim); } } }
然后在触发时调用:
if (timesTicked == 59) { string voedsel = "Food1"; AnimateFood(voedsel); MyAnimationBoard1.Begin(); } // 其他触发逻辑同理
方案二:动态创建动画(更适合9个元素的场景)
如果需要为不同元素设置不同的启动时间,或者避免XAML中重复定义动画,推荐动态创建动画逻辑,这样更灵活:
第一步:封装动画创建逻辑
先写一个方法生成旋转动画的关键帧模板:
private DoubleAnimationUsingKeyFrames CreateRotationAnimation(TimeSpan startTimeOffset) { var anim = new DoubleAnimationUsingKeyFrames(); // 绑定旋转角度属性,和XAML保持一致 anim.TargetProperty = "(UIElement.RenderTransform).(RotateTransform.Angle)"; // 添加关键帧,时间基于传入的偏移量计算 anim.KeyFrames.Add(new LinearDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.Zero))); anim.KeyFrames.Add(new LinearDoubleKeyFrame(30, KeyTime.FromTimeSpan(startTimeOffset + TimeSpan.FromSeconds(0.5)))); anim.KeyFrames.Add(new LinearDoubleKeyFrame(-30, KeyTime.FromTimeSpan(startTimeOffset + TimeSpan.FromSeconds(1.0)))); anim.KeyFrames.Add(new LinearDoubleKeyFrame(30, KeyTime.FromTimeSpan(startTimeOffset + TimeSpan.FromSeconds(2.0)))); anim.KeyFrames.Add(new LinearDoubleKeyFrame(-30, KeyTime.FromTimeSpan(startTimeOffset + TimeSpan.FromSeconds(3.0)))); anim.KeyFrames.Add(new LinearDoubleKeyFrame(30, KeyTime.FromTimeSpan(startTimeOffset + TimeSpan.FromSeconds(4.0)))); return anim; }
第二步:实现动态绑定目标并启动动画
public void AnimateFood(string targetElementName, TimeSpan startTimeOffset) { // 清空Storyboard之前的动画,避免冲突 MyAnimationBoard1.Children.Clear(); // 创建动画并设置目标 var rotationAnim = CreateRotationAnimation(startTimeOffset); Storyboard.SetTargetName(rotationAnim, targetElementName); // 添加到Storyboard并启动 MyAnimationBoard1.Children.Add(rotationAnim); MyAnimationBoard1.Begin(); }
第三步:触发时调用
if (timesTicked == 59) { AnimateFood("Food1", TimeSpan.FromSeconds(0)); // 立即启动 } else if (timesTicked == 52) { AnimateFood("Food3", TimeSpan.FromSeconds(4)); // 4秒后启动,和你原来的第二个动画一致 Debug.WriteLine("Tweede animatie"); } else if (timesTicked == 46) { AnimateFood("Food8", TimeSpan.FromSeconds(8)); // 自定义启动时间 Debug.WriteLine("Derde animatie"); }
关键注意事项
- 确保所有目标图片(如
Food1、Food3)在XAML中已定义RenderTransform为RotateTransform,否则动画无法生效:<Image x:Name="Food1" Source="YourImagePath.png"> <Image.RenderTransform> <RotateTransform Angle="0"/> </Image.RenderTransform> </Image> - 如果你需要同时播放多个动画,可以跳过
Clear()步骤,直接添加新的动画到Storyboard中。 - 注意XAML中
KeyTime的格式是hh:mm:ss.fff,比如0:0:0.10代表0.1秒,如果你想设置1秒的话应该写0:0:1。
内容的提问来源于stack exchange,提问作者Sander Bloem
相关产品推荐
相关产品推荐

