无法以编程方式在WPF中设置动画控件的宽度或高度(甚至不能通过Snoop)

时间:2013-09-25 16:31:44

标签: c# wpf animation

这可能与动画有关。我有一个WPF控件,其宽度和高度我通过几个不同的故事板动画。我创建了故事板,然后在它们上面调用Begin()。我提供了故事板如下图所示的代码。

我想在某个事件(例如窗口调整大小)上重新评估控件大小,以便它与动画的值不同。我尝试通过设置我的控件的WidthHeight属性手动(在动画运行后)在SizeChanged上处理此问题。调试器显示未设置这些值(原始值保持不变)。

当我通过Snoop检查WPF时,Width和Height行以桃色/橙色突出显示并尝试再次通过它设置值不会持续存在(当我聚焦时会显示原始值。我的猜测是我的动画以某种方式覆盖了对属性的手动更改,但我不确定这是真的还是如何解决它。

故事板类

public class MyAnimationClass
{
    private Storyboard _myStoryboard;
    private DoubleAnimation _animation1;
    private DoubleAnimation _animation2;
    private DoubleAnimation _animation3;

    private void InitializeStoryboard()
    {
        _myStoryboard = CreateMyStoryboard(out _animation1, out _animation2, out _animation3);
    }

    private Storyboard CreateMyStoryboard(out DoubleAnimation animation1, out DoubleAnimation animation2, out DoubleAnimation animation3)
    {
        var myStoryboard = new Storyboard();

        // create animations
        animation1 = new DoubleAnimation { Duration = new TimeSpan(0, 0, 0, 0, 250), From = 0, To = 0 };
        animation2 = new DoubleAnimation { BeginTime = new TimeSpan(), Duration = new TimeSpan(0, 0, 0, 0, 250), From = 35, To = 35 };
        animation3 = new DoubleAnimation { BeginTime = new TimeSpan(0, 0, 0, 0, 250), Duration = new TimeSpan(0, 0, 0, 0, 250), From = 35, To = 0 };

        Storyboard.SetTargetProperty(animation1, new PropertyPath(FrameworkElement.WidthProperty));
        Storyboard.SetTargetProperty(animation2, new PropertyPath(FrameworkElement.HeightProperty));
        Storyboard.SetTargetProperty(animation3, new PropertyPath(FrameworkElement.HeightProperty));

        myStoryboard.Children.Add(animation1);
        myStoryboard.Children.Add(animation2);
        myStoryboard.Children.Add(animation3);

        return myStoryboard;
    }

    public void Animate(Control controlToAnimate)
    {
        // ....

        var finalWidth = CalculateFinalWidth();
        var finalHeight = CalculateFinalHeight();

        _animation1.To = finalWidth;
        _animation3.To = finalHeight;
        _myStoryboard.Begin(controlToAnimate);
    }
}

当我想为某些内容制作动画时,我会在Animate()类的实例上调用MyAnimationClass

思想?

1 个答案:

答案 0 :(得分:2)

这最终是一个非常简单的修复。由于FillBehavior控制了属性值,因此值没有变化。但是,简单地将其更改为FillBehavior.Stop并没有解决我的问题,因为当我的非动画代码设置宽度/高度时,下次我的动画运行它会动画到我想要的宽度/高度然后默认回到设定高度。这是通过在计算之后和动画之前设置控件的宽度/高度来解决的:

public void Animate(Control controlToAnimate)
{
    // ....

    var finalWidth = CalculateFinalWidth();
    var finalHeight = CalculateFinalHeight();

    // set values here so after animation they stay
    controlToAnimate.Width = finalWidth;
    controlToAnimate.Height = finalHeight;

    _animation1.To = finalWidth;
    _animation3.To = finalHeight;
    _myStoryboard.Begin(controlToAnimate);
}