【问题标题】:Convert C# animation code to storyboard将 C# 动画代码转换为情节提要
【发布时间】:2012-07-30 09:05:45
【问题描述】:

我有以下有效的方法。我想把它放在一个返回故事板的实用方法中。我将其转换为故事板的每一次尝试都失败了,我花了很多时间进行研究。除非有人来救我,否则我已经准备好放弃了。

这是我要转换的代码:

public override void Begin(FrameworkElement element, int duration)
{
    var transform = new ScaleTransform();
    element.LayoutTransform = transform;

    var animation = new DoubleAnimation
                        {
                            From = 1,
                            To = 0,
                            Duration = TimeSpan.FromMilliseconds(duration),
                            FillBehavior = FillBehavior.Stop,
                            EasingFunction = new QuinticEase { EasingMode = EasingMode.EaseIn }
                        };

    transform.BeginAnimation(ScaleTransform.ScaleXProperty, animation);
    transform.BeginAnimation(ScaleTransform.ScaleYProperty, animation);
}

所以,我想返回一个 Storyboard,而不是两个 BeginAnimation() 调用,所以我所要做的就是调用 storyboard.Begin()。我知道这应该不难做到,但我就是不明白。

谢谢。

编辑:响应 H.B 的建议,我尝试了以下代码,但仍然无法正常工作:

private static Storyboard CreateAnimationStoryboard(FrameworkElement element, int duration)
{
    var sb = new Storyboard();
    var scale = new ScaleTransform(1, 1);
    element.RenderTransform = scale;
    element.RegisterName("scale", scale);

    var animation = new DoubleAnimation
    {
        From = 1,
        To = 0,
        Duration = TimeSpan.FromMilliseconds(duration),
        FillBehavior = FillBehavior.Stop,
        EasingFunction = new QuinticEase { EasingMode = EasingMode.EaseIn }
    };
    sb.Children.Add(animation);

    Storyboard.SetTarget(animation, scale);
    Storyboard.SetTargetProperty(animation, new PropertyPath(ScaleTransform.ScaleXProperty));

    return sb;
}

我知道我只为 X 轴设置了动画 - 只是想先让一些东西工作。

【问题讨论】:

    标签: c# wpf animation storyboard


    【解决方案1】:

    您需要两个动画,然后使用SetTargetPropertySetTargetName 将附加的Storyboard 属性设置为正确对象上的正确属性。

    由于故事板的工作方式,您还需要设置名称范围 (NameScope.SetNameScope),注册转换的名称,并使用 containing element overload 调用 StoryBoard.Begin

    例如

    NameScope.SetNameScope(element, new NameScope());
    
    var transform = new ScaleTransform();
    var transformName = "transform";
    element.RegisterName(transformName, transform);
    element.RenderTransform = transform;
    
    var xAnimation = new DoubleAnimation(2, TimeSpan.FromSeconds(1));
    var yAnimation = xAnimation.Clone();
    
    var storyboard = new Storyboard()
    {
        Children = { xAnimation, yAnimation }
    };
    
    Storyboard.SetTargetProperty(xAnimation, new PropertyPath("(ScaleTransform.ScaleX)"));
    Storyboard.SetTargetProperty(yAnimation, new PropertyPath("(ScaleTransform.ScaleY)"));
    
    Storyboard.SetTargetName(xAnimation, transformName);
    Storyboard.SetTargetName(yAnimation, transformName);
    
    storyboard.Begin(element);
    

    【讨论】:

    • 是的,我得到了这么多。也许您提到的并发症的细节可能会有所帮助?
    • @DanThomas: This 听起来是个问题。
    • 谢谢,但如果您要在代码中创建框架元素,我不会这样做。框架元素已经通过 xaml 存在,我正在通过附加行为调用此方法。还有其他想法吗? :)
    • @DanThomas:您正在为转换设置动画,这需要一个名称。此外,创建 XAML 可能还不够,您还需要在 XAML 中设置 Name,关键是如果您希望在 XAML 中进行动画处理,您总是需要设置名称,否则你不能引用它。
    • @DanThomas:差不多,看看我编辑的答案。 (我没有让它与 SetTarget 一起工作,不知道这在代码中是否有任何用途)
    【解决方案2】:

    我建议使用Expression Blend 并从那里开始录制,它应该在 XAML 中创建您的故事板。而不是使用 C# 对其进行硬编码并尝试将其一一翻译到情节提要,因此它可能很容易出错。

    【讨论】:

    • 谢谢,但我需要在代码中完成。我创建了一个附加到元素并绑定到 ViewModel 属性的行为,该属性允许 ViewModel 触发动画可见性转换,并在完成后回调 ViewModel。我想仍然可以在 xaml 中创建动画,但是由于完成后我需要回调,所以在代码中做所有事情都更容易。
    猜你喜欢
    • 2012-02-13
    • 2011-08-17
    • 2017-04-06
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-15
    • 1970-01-01
    相关资源
    最近更新 更多