在控件中更改属性之前和之后播放动画

时间:2014-09-30 19:41:51

标签: c# animation winrt-xaml dependency-properties

我已经构建了一个自定义控件。其中一个名为Date的属性由依赖项属性DateProperty备份。我想要的是,当此属性更改时,播放动画,然后控件响应此更改,然后播放另一个动画。这就是我所做的:

public DateTime Date
{
    get
    {
        return (DateTime)GetValue(DateProperty);
    }
    set
    {
        SetValue(DateProperty, value);
    }
}

// Using a DependencyProperty as the backing store for Date. This enables animation,
// styling, binding, etc...

public static readonly DependencyProperty DateProperty = DependencyProperty.Register("Date", typeof(DateTime), typeof(MyCtl), new PropertyMetadata(DateTime.Now, OnDatePropertyChanged));

private static void OnDatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    MyCtl elem = d as MyCtl;
    if (elem != null)
    {
        elem.shrinkStoryboard.Begin();

        // Some irrelevant processing

        // Some processing that modifies the control in response to the property changes

        elem.growStoryboard.Begin();
    }
}

这似乎不起作用。当我评论出其中一个故事板时,它有效,但只有那个故事板才能播放,这就是我想要的。我还注意到动画中没有考虑BeginTimeDuration值。

动画仅影响RenderTransform

如果有任何人需要知道的信息,我会更新问题。

编辑

正如其名称所暗示的那样,两个故事板会减少并增加ScaleX的{​​{1}}和ScaleY值。因此,我不能将它们组合在一个故事板中。如果有人需要XAML,我会尽快发布。

XAML

ScaleTransform

代码隐藏

<Storyboard x:Name="shrinkStoryBoard"
            Storyboard.TargetName="shrink"
            Duration="0:0:0.5">
    <DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
                     To="0.001" />
    <DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
                     To="0.001" />
</Storyboard>
<Storyboard x:Name="growStoryBoard"
            Storyboard.TargetName="shrink"
            BeginTime="0:0:0.7"
            Duration="0:0:0.5">
    <DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
                     To="1" />
    <DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
                     To="1" />
</Storyboard>

2 个答案:

答案 0 :(得分:0)

两个故事板之间的属性处理没有(或者至少不应该)显着的时间,因此第二个动画正在开始,而第一个动画仍在播放。因为他们正在修改干扰和覆盖第一个的相同属性。

最简单的解决方案是使用单个故事板缩小然后增长 - 您可以将其设置为自动反转。如果您想使用单独的故事板,请等到shrinkStoryboard的Completed事件在Beginning growStoryboard之前触发。

答案 1 :(得分:0)

我终于能够让这个工作了。这就是我所做的(我不知道为什么我从未想过它):

private static void OnDatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    CalendarEntryHorizontal elem = d as CalendarEntryHorizontal;
    if (elem != null)
    {
        elem.shrinkStoryboard.Completed += (o, ev) =>
        {
            DateTime date = (DateTime)e.NewValue;
            string month = date.ToString("MMMM").Substring(0, 3);
            string day = date.Day.ToString("D2");
            string year = date.Year.ToString("D4");

            // ...

            elem.growStoryboard.Begin();
        };

        elem.shrinkStoryboard.Begin();
    }
}