是否可以在不重新启动整个动画的情况下更新DoubleAnimation.FromProperty?

时间:2010-08-19 09:07:15

标签: wpf animation storyboard

我还不是很熟悉很多WPF,所以如果这个查询背叛了一些明显的误解,我会很感激他们被指出。

我正在尝试(好或坏)将DoubleAnimation.FromProperty与包含/运行动画的StackPanel的实际宽度同步。

我最初尝试使用数据绑定,例如

BindingOperations.SetBinding(anim, 
   DoubleAnimation.FromProperty, 
   new Binding {Source = panel, Path = new PropertyPath(ActualWidthProperty)});

但这似乎不起作用。虽然我可以将文本框绑定到From属性并看到它正在更改,但动画将继续从初始值运行。这与故事板冻结有什么关系吗? (我对此一无所知,但刚刚听说过)

然后我想为什么不停止并重新启动故事板(关闭它再打开!),同时通过处理StackPanel.SizeChanged事件来更改FromProperty。像这样:

void panel_SizeChanged(object sender, SizeChangedEventArgs e)
{
    if (myStoryBoard != null && myStoryBoard.GetCurrentState(panel) == ClockState.Active)
    {
        myStoryBoard.Stop(panel);
        foreach(var child in myStoryBoard.Children)
        {
            var anim = child as DoubleAnimation;
            if (anim == null) continue;
            anim.From = panel.ActualWidth;
        }
        myStoryBoard.Begin(panel, true);
    }
}

这是有效的,但是,当然,每次调整面板大小时,它都会从头开始动画。我更喜欢的是能够从被中断的点恢复动画但是使用新的FromProperty。这甚至可能吗?

1 个答案:

答案 0 :(得分:1)

比你想象的容易得多。 WPF和Silverlight中关于动画的很酷的事情是它们可以与当前情况相关。您需要做的唯一事情就是创建一个相对动画,例如创建带有To的DoubleAnimation但不填写From。

下面的示例是将stackpanel的不透明度从当前值设置为1:

<DoubleAnimation Duration="0:0: To="1" 
     Storyboard.TargetName="LayoutRoot" 
     Storyboard.TargetProperty="StackPanel.Opacity" />

EDIT1:
使动画循环回到其原始值而不使用from和loop forever

<Storyboard AutoReverse="True" RepeatBehavior="Forever">
    <DoubleAnimation Duration="0:0:2" 
                        To="1"
                        Storyboard.TargetName="LayoutRoot"
                        Storyboard.TargetProperty="StackPanel.Opacity"
                        />
</Storyboard>