【问题标题】:How to Animate Transforms in code behind如何在后面的代码中为变换设置动画
【发布时间】:2017-03-08 13:36:03
【问题描述】:

我有一个自定义按钮。出于某种原因,我想在后面的代码中应用转换。并且转换工作正常。但是当我尝试在变换上添加动画时,动画不会生效。我的代码如下。

    public partial class MyButton : Button
    {
        private TranslateTransform translate = new TranslateTransform() { X = 200, Y = 100 };

        public MyButton()
        {
            InitializeComponent();
            this.RenderTransform = new TransformGroup()
            {
                Children = 
                {
                    this.translate
                }
            };
        }

        protected override void OnClick()
        {
            base.OnClick();
            // Edit: I need to use Storyboard to synchronized animation1 and animation2.
            var sb = new Storyboard();
            var animation1 = new DoubleAnimation(200, -10, new Duration(new TimeSpan(0, 0, 0, 1, 0)));
            Storyboard.SetTarget(animation1, this.translate);
            Storyboard.SetTargetProperty(animation1, new PropertyPath("X"));
            sb.Children.Add(animation1);

            var animation2 = new DoubleAnimation(100, 0, new Duration(new TimeSpan(0, 0, 0, 1, 0)));
            Storyboard.SetTarget(animation2, this.translate);
            Storyboard.SetTargetProperty(animation2, new PropertyPath("Y"));
            sb.Children.Add(animation2);                
            sb.Begin(this);
        }
    }

谁能解释一下为什么以及如何为这个场景添加动画?

【问题讨论】:

    标签: wpf wpf-controls


    【解决方案1】:

    OP 说他毕竟需要一个故事板。问题似乎在于有时SetTarget() 不起作用。我不知道为什么不,我没有研究过。我刚刚测试了the workaround,感觉不错。

    请注意,您必须在构造函数中执行 NameScope/RegisterName 内容。

    public MyButton()
    {
        InitializeComponent();
    
        this.RenderTransform = new TransformGroup()
        {
            Children =
            {
                this.translate
            }
        };
    
        NameScope.SetNameScope(this, new NameScope());
        RegisterName("translate", this.translate);
    }
    
    protected override void OnClick()
    {
        base.OnClick();
    
        var sb = new Storyboard();
        var animation1 = new DoubleAnimation(200, -10, new Duration(new TimeSpan(0, 0, 0, 1, 0)));
        Storyboard.SetTargetName(animation1, "translate");
        Storyboard.SetTargetProperty(animation1, new PropertyPath(TranslateTransform.XProperty));
        sb.Children.Add(animation1);
    
        var animation2 = new DoubleAnimation(100, 0, new Duration(new TimeSpan(0, 0, 0, 1, 0)));
        Storyboard.SetTargetName(animation2, "translate");
        Storyboard.SetTargetProperty(animation2, new PropertyPath(TranslateTransform.YProperty));
        sb.Children.Add(animation2);
    
        sb.Begin(this);
    }
    

    简单的解决方案

    您无需使用相同的参数创建两个不同的动画。原来你也不需要故事板。那是为事件或其他东西启动动画。我不知道你为什么不谷歌这个。谷歌将它用于“wpf 故事板动画......”的自动完成功能。 It's here, anyway

    protected override void OnClick()
    {
        base.OnClick();
    
        var animation1 = new DoubleAnimation(100, 0, 
                             new Duration(new TimeSpan(0, 0, 0, 1, 0)));
    
        translate.BeginAnimation(TranslateTransform.XProperty, animation1);
        translate.BeginAnimation(TranslateTransform.YProperty, animation1);
    }
    

    【讨论】:

    • 感谢您提供此信息。但实际上,我仍然需要一个故事板。 OnClick 中的代码只是一个简化的代码。我不希望动画立即开始,因为我有很多动画要同时开始。我需要先创建故事板,然后在某些条件下开始。
    • @NewtonZou 已更新解决方案
    • 完美!出色的!精彩的!对于 NameScope/RegisterName 的东西,我猜我们在 XAML 中制作动画时会在幕后调用它。
    猜你喜欢
    • 1970-01-01
    • 2011-04-15
    • 2011-04-17
    • 2018-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多