发出用户控制脉冲

Making a user control pulse

我想做的是让我的控件 "pulse"(放大一点,然后缩小一点,然后恢复到正常大小)。下面的代码完全符合我的要求,但似乎应该有更简单的方法。它必须在代码隐藏中完成,因为这是我们大多数控件派生的抽象 class。我对动画控制和故事板没有太多经验。

具体来说,我的问题是,是否有比以下方法更简单的方法来获得所需的结果(同时仍在代码隐藏中完成)?

    public void Pulse()
    {
        var storyboard = new Storyboard
        {
            FillBehavior = FillBehavior.Stop,
            RepeatBehavior = new RepeatBehavior(2)
        };

        double timeIncrement = .15;
        double changePercent = 20;

        var firstTime = TimeSpan.FromSeconds(timeIncrement);
        var secondTime = TimeSpan.FromSeconds(timeIncrement * 3);
        var thirdTime = TimeSpan.FromSeconds(timeIncrement * 4);

        var scale = new ScaleTransform(1.0, 1.0);

        RenderTransformOrigin = new Point(.5, .5);
        RenderTransform = scale;

        //enlarge
        {
            DoubleAnimation growX = new DoubleAnimation
            {
                Duration = firstTime,
                To = 1 + changePercent
            };
            storyboard.Children.Add(growX);
            Storyboard.SetTargetProperty(growX, new PropertyPath("RenderTransform.ScaleX"));

            DoubleAnimation growY = new DoubleAnimation
            {
                Duration = firstTime,
                To = 1 + changePercent
            };
            storyboard.Children.Add(growY);
            Storyboard.SetTargetProperty(growY, new PropertyPath("RenderTransform.ScaleY"));
        }

        //shrink
        {
            DoubleAnimation shrinkX = new DoubleAnimation
            {
                Duration = secondTime,
                To = 1 - changePercent
            };
            storyboard.Children.Add(shrinkX);
            Storyboard.SetTargetProperty(shrinkX, new PropertyPath("RenderTransform.ScaleX"));

            DoubleAnimation shrinkY = new DoubleAnimation
            {
                Duration = secondTime,
                To = 1 - changePercent
            };
            storyboard.Children.Add(shrinkY);
            Storyboard.SetTargetProperty(shrinkY, new PropertyPath("RenderTransform.ScaleY"));
        }

        //back to normal
        {
            DoubleAnimation normX = new DoubleAnimation
            {
                Duration = thirdTime,
                To = 1
            };
            storyboard.Children.Add(normX);
            Storyboard.SetTargetProperty(normX, new PropertyPath("RenderTransform.ScaleX"));

            DoubleAnimation normY = new DoubleAnimation
            {
                Duration = thirdTime,
                To = 1
            };
            storyboard.Children.Add(normY);
            Storyboard.SetTargetProperty(normY, new PropertyPath("RenderTransform.ScaleY"));
        }

        BeginStoryboard(storyboard, HandoffBehavior.SnapshotAndReplace, false);
    }

这是一个很好的方法,WPF 不提供自动脉冲的方法或事件。你的很简单,当你创建它时,你知道如何根据需要修改它。

您或许可以通过将 grow/shrink 逻辑移动到它自己的方法中来稍微简化一些事情。这减少了重复并提供了一个潜在的更可重用的代码 kibble。

public void Pulse()
{
    var storyboard = new Storyboard
    {
        FillBehavior = FillBehavior.Stop,
        RepeatBehavior = new RepeatBehavior(2)
    };

    double timeIncrement = .15;

    double growPercent = 20;
    double shrinkPercent = -20;

    var firstTime = TimeSpan.FromSeconds(timeIncrement);
    var secondTime = TimeSpan.FromSeconds(timeIncrement * 3);
    var thirdTime = TimeSpan.FromSeconds(timeIncrement * 4);

    var scale = new ScaleTransform(1.0, 1.0);

    RenderTransformOrigin = new Point(.5, .5);
    RenderTransform = scale;

    storyboard = AddSizeChange(firstTime, growPercent, storyboard);
    storyboard = AddSizeChange(secondTime, shrinkPercent, storyboard);
    storyboard = AddSizeChange(thirdTime, growPercent, storyboard);

    BeginStoryboard(storyboard, HandoffBehavior.SnapshotAndReplace, false);
}

public Storyboard AddSizeChange(TimeSpan animTime, double changePercent, Storyboard storyboard)
{
    DoubleAnimation growX = new DoubleAnimation
    {
        Duration = animTime,
        To = 1 + changePercent
    };
    storyboard.Children.Add(growX);
    Storyboard.SetTargetProperty(growX, new PropertyPath("RenderTransform.ScaleX"));

    DoubleAnimation growY = new DoubleAnimation
    {
        Duration = animTime,
        To = 1 + changePercent
    };
    storyboard.Children.Add(growY);
    Storyboard.SetTargetProperty(growY, new PropertyPath("RenderTransform.ScaleY"));

    return storyboard;
}