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

其他阅读

管道技术——中间件的灵魂

在现代Web开发中,中间件技术使用越来越广泛,本文带大家了解中间件的基础,同时也是中间件的灵魂所在,管道技术。在C#中,依赖于委托,我们可以很容易就实现一个中间件管道。所以在阅读本文前,请确保你已经学会了什么是委托,包括但不限于Delegate,Action,Func。除此之外,本文还会使用到反射相关知识,请确保你已经学会了什么是反射。

新版本.Net关于Process.Start的问题

.Net 开发中,试用 Process.Start() 来启动一个新进程,当我们传入的是具体文件或者链接的时候,系统也会根据默认打开方式打开对应的进程。但是在新版本的 .Net 中,试用 Process.Start() 来打开文件或者链接的时候,会抛出 System.ComponentModel.Win32Exception 的错误,提示系统找不到指定的文件。

浅析web前端中的MVC模式

MVC是常见的软件架构设计模式,它通过分离关注点改进代码的组织方式。区别于软件设计模式,只是为了解决问题总结出的抽象方法,一种架构模式种往往会用到多种设计模式。

命令行打包.net项目

.net 日常开发中,我们接触最多的就是 Visual Studio ,它是微软为了 .net 平台专门打造的 IDE (集成开发环境),为整个 .net 平台开发带来了无与伦比的图形化体验,但是有时候,我们也会遇到需要通过命令行来生成 .net 项目的情况,本文会介绍几种命令行打包的姿势。

Linux中查看,添加,修改,删除用户和用户组

将用户分组是Linux系统中对用户进行管理及控制访问权限的一种手段。某个用户都属于某个用户组;一个组中可以有多个用户,一个用户也可以属于不同的组。当一个用户同时是多个组中的成员时,登录时所属的为默认组,而其他组称为附加组。本文将会介绍在 Linux 中查看,添加,修改,删除用户和用户组,注意:权限管理非常重要,可能一不小心就导致系统无法登录,请谨慎操作