WPF中创建一个矩形圆角动画

WPF 中内置了好几种动画,大多数场景可以坐到开箱即用,不过并没有内置 CornerRadiusAnimation ,本文将会介绍怎么实现一个 CornerRadiusAnimation 动画,实现 BorderCornerRadius 属性动画效果。

动画类 CornerRadiusAnimation

WPF 中,所有的动画都是继承于 AnimationTimeline 类型,我们自定义的 CornerRadiusAnimation 类也应该继承于该类。

public class CornerRadiusAnimation : AnimationTimeline
{
    
}

照猫画虎,在动画中,我们需要定义一个 From ,一个 To ,用来表示动画的初始状态和结束状态,我们的动画是应用于 CornerRadius 属性,那 FromTo 都应该是 CornerRadius 类型。然后注册对应的依赖属性,用于在 xaml 中进行绑定。

public CornerRadius From
{
    get => (CornerRadius)GetValue(FromProperty);
    set => SetValue(FromProperty, value);
}

public static readonly DependencyProperty FromProperty = DependencyProperty.Register("From", typeof(CornerRadius), typeof(CornerRadiusAnimation));

public CornerRadius To
{
    get => (CornerRadius)GetValue(ToProperty);
    set => SetValue(ToProperty, value);   
}

public static readonly DependencyProperty ToProperty = DependencyProperty.Register("To", typeof(CornerRadius), typeof(CornerRadiusAnimation));

接下来,我们要对基类的属性和方法进行重写, TargetPropertyType 属性用来定义我们的动画需要作用的类型,CreateInstanceCore() 方法实现了创建动画实例,GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock) 方法实现了当前的值,在动画播放时会被重复调用,达到动画效果。

public override Type TargetPropertyType => typeof(CornerRadius);


public override Freezable CreateInstanceCore(){
    return new CornerRadiusAnimation();
}


public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock)
{
    if(animationClock.CurrentProgress == null)
    {
        return From;
    }

    double progress = animationClock.CurrentProgress.Value;

    return new CornerRadius(
        From.TopLeft + (To.TopLeft = From.TopLeft) * progress,
        From.TopRight + (To.TopRight = From.TopRight ) * progress,
        From.BottomRight + (To.BottomRight = From.BottomRight ) * progress,
        From.BottomLeft + (To.BottomLeft = From.BottomLeft ) * progress
    );
}

使用

XAML

xaml 中定义一个 Border 控件,设置初始状态下的 CornerRadius 属性值,在资源中引入我们写好的 CornerRadiusAnimation ,设置 FromTo 属性值,这里设置为 0 和 30,预期结果是 Border 控件的会从直角矩形慢慢变成圆角矩形。

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApp"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Storyboard x:Key="CornerRadiusAnimation">
            <local:CornerRadiusAnimation Storyboard.TargetProperty="(Border.CornerRadius)" 
                                         Storyboard.TargetName="MyBorder" 
                                         From="0,0,0,0" To="30,30,30,30" 
                                         Duration="0:0:2" />
        </Storyboard>
    </Window.Resources>
    <Grid>
        <Border x:Name="MyBorder" Width="200" Height="200" Background="LightBlue" CornerRadius="0,0,0,0">
        </Border>
        <Button Content="播放" Margin="0,0,0,20" Click="Button_Click"/>
    </Grid>
</Window>

C#

在窗体的后台代码中,我们来实现 Button_Click 事件,在事件中调用动画对象的 Begin() 方法进行播放。

using System.Windows;
using System.Windows.Media.Animation;

namespace WpfApp
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Storyboard sb = (Storyboard)this.Resources["CornerRadiusAnimation"];
            sb.Begin();
        }
    }
}
发布时间:2024-11-27
其他阅读

Angular 中跨分模块后路由复用问题

当我们的 Angular 应用越来越大后,就需要考虑使用模块或者直接使用库来将解体应用,使用时进来懒加载,加快访问速度。当跨分模块后,普通的路由复用策略就是失效,需要额外的解决方法。

查看原文

Apple中的模糊效果

本文主要介绍在前端里比较重要的一个效果——高斯模糊效果,也有人称为毛玻璃特效。在Mac和Windows系统样式上也都在使用模糊效果。下面聚焦于Web前端中的模糊效果开发。

查看原文

C#中new和override的区别

在C#编程语言中,new 和 override 是两个重要的关键字,它们用于控制类成员方法的行为。在面向对象编程(OOP)中,理解这两个关键字的区别和用法,对于编写清晰、可维护和高效的代码至关重要。

查看原文

Apple网页中滚动效果

打开Apple官网查看iPhone页面,我们可以看到一个特殊效果,当你滚动鼠标时,页面不出现滚动效果,但内容却在变化。现在,基于 position : sticky 可以很容易实现这个效果。

查看原文

记录中文名WPF应用无法启动

今年开春,突然就收到部分用户反馈软件无法启动的问题,沟通后远程查看发现应用刚启动就直接崩溃了,在Windows的事件查看器可以看到应用的崩溃日志,发现是 ucrtbase.dll 模块崩溃,错误代码 0x0000409

查看原文