实现效果

今天以一个交互式小球的例子跟大家分享一下wpf动画中DoubleAnimation的基本使用。该小球会移动到我们鼠标左键或右键点击的地方。

该示例的实现效果如下所示:

页面设计

xaml如下所示:

<Window x:Class="AnimationDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationDemo"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<DockPanel>
<Border x:Name="_containerBorder" Background="Transparent">
<Ellipse x:Name="_interactiveEllipse"
Fill="Lime"
Stroke="Black"
StrokeThickness="2.0"
Width="25"
Height="25"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
</Border>
</DockPanel>
</Window>

就是在DockPanel中包含一个Border,在Border中包含一个圆形。

页面设计的效果如下所示:

一些设置

相关设置的cs代码如下所示:

   public partial class MainWindow : Window
{
private readonly TranslateTransform _interactiveTranslateTransform;
public MainWindow()
{
InitializeComponent(); _interactiveTranslateTransform = new TranslateTransform(); _interactiveEllipse.RenderTransform =
_interactiveTranslateTransform; _containerBorder.MouseLeftButtonDown +=
border_mouseLeftButtonDown;
_containerBorder.MouseRightButtonDown +=
border_mouseRightButtonDown;
}
 private readonly TranslateTransform _interactiveTranslateTransform;

首先声明了一个私有的只读的TranslateTransform类型的对象_interactiveTranslateTransform,然后在MainWindow的构造函数中赋值。

 _interactiveTranslateTransform = new TranslateTransform();

TranslateTransform是什么?有什么作用呢?

它的基本结构:

 //
// 摘要:
// Translates (moves) an object in the 2-D x-y coordinate system.
public sealed class TranslateTransform : Transform
{ public static readonly DependencyProperty XProperty; public static readonly DependencyProperty YProperty; public TranslateTransform(); public TranslateTransform(double offsetX, double offsetY); public override Matrix Value { get; } public double X { get; set; } public double Y { get; set; } public TranslateTransform Clone(); public TranslateTransform CloneCurrentValue();
protected override Freezable CreateInstanceCore();
}

TranslateTransform 是 WPF 中的一个类,它表示一个 2D 平移变换。这个类是 Transform 类的派生类,用于在 2D 平面上移动(平移)对象。

TranslateTransform 类有两个主要的属性:X 和 Y,它们分别表示在 X 轴和 Y 轴上的移动距离。例如,如果你设置 X 为 100 和 Y 为 200,那么应用这个变换的元素将会向右移动 100 像素,向下移动 200 像素。

 _interactiveEllipse.RenderTransform =
_interactiveTranslateTransform;

_interactiveEllipse元素的RenderTransform属性设置为_interactiveTranslateTransform

RenderTransform属性用于获取或设置影响 UIElement 呈现位置的转换信息。

 _containerBorder.MouseLeftButtonDown +=
border_mouseLeftButtonDown;
_containerBorder.MouseRightButtonDown +=
border_mouseRightButtonDown;

这是在注册 _containerBorder的鼠标左键点击事件与鼠标右键点击事件。

注意当Border这样写时,不会触发鼠标点击事件:

 <Border x:Name="_containerBorder">

这是因为在 WPF 中,Border 控件的背景默认是透明的,这意味着它不会接收鼠标事件。当你设置了背景颜色后,Border 控件就会开始接收鼠标事件,因为它现在有了一个可见的背景。

如果你希望 Border 控件在没有背景颜色的情况下也能接收鼠标事件,你可以将背景设置为透明色。这样,虽然背景看起来是透明的,但它仍然会接收鼠标事件。

可以这样设置:

<Border x:Name="_containerBorder" Background="Transparent">

鼠标点击事件处理程序

以鼠标左键点击事件处理程序为例,进行说明:

  private void border_mouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var clickPoint = Mouse.GetPosition(_containerBorder); // Set the target point so the center of the ellipse
// ends up at the clicked point.
var targetPoint = new Point
{
X = clickPoint.X - _interactiveEllipse.Width / 2,
Y = clickPoint.Y - _interactiveEllipse.Height / 2
}; // Animate to the target point.
var xAnimation =
new DoubleAnimation(targetPoint.X,
new Duration(TimeSpan.FromSeconds(4)));
_interactiveTranslateTransform.BeginAnimation(
TranslateTransform.XProperty, xAnimation, HandoffBehavior.SnapshotAndReplace); var yAnimation =
new DoubleAnimation(targetPoint.Y,
new Duration(TimeSpan.FromSeconds(4)));
_interactiveTranslateTransform.BeginAnimation(
TranslateTransform.YProperty, yAnimation, HandoffBehavior.SnapshotAndReplace); // Change the color of the ellipse.
_interactiveEllipse.Fill = Brushes.Lime;
}

重点是:

 // Animate to the target point.
var xAnimation =
new DoubleAnimation(targetPoint.X,
new Duration(TimeSpan.FromSeconds(4)));
_interactiveTranslateTransform.BeginAnimation(
TranslateTransform.XProperty, xAnimation, HandoffBehavior.SnapshotAndReplace); var yAnimation =
new DoubleAnimation(targetPoint.Y,
new Duration(TimeSpan.FromSeconds(4)));
_interactiveTranslateTransform.BeginAnimation(
TranslateTransform.YProperty, yAnimation, HandoffBehavior.SnapshotAndReplace);

DoubleAnimation类的介绍:

DoubleAnimation 是 WPF 中的一个类,它用于创建从一个 double 值到另一个 double 值的动画。这个类是 AnimationTimeline 类的派生类,它可以用于任何接受 double 类型的依赖属性。

DoubleAnimation 类有几个重要的属性:

• From:动画的起始值。

• To:动画的结束值。

• By:动画的增量值,用于从 From 值增加或减少。

• Duration:动画的持续时间。

• AutoReverse:一个布尔值,指示动画是否在到达 To 值后反向运行回 From 值。

• RepeatBehavior:定义动画的重复行为,例如,它可以设置为无限重复或重复特定的次数。

  var xAnimation =
new DoubleAnimation(targetPoint.X,
new Duration(TimeSpan.FromSeconds(4)));

我们使用的是这种形式的重载:

设置了一个要达到的double类型值与达到的时间,这里设置为了4秒。

 _interactiveTranslateTransform.BeginAnimation(
TranslateTransform.XProperty, xAnimation, HandoffBehavior.SnapshotAndReplace);

• _interactiveTranslateTransform.BeginAnimation:这是 BeginAnimation 方法的调用,它开始一个动画,该动画会改变一个依赖属性的值。在这个例子中,改变的是 _interactiveTranslateTransform 对象的 X 属性。

• TranslateTransform.XProperty:这是 TranslateTransform 类的 X 依赖属性。这个属性表示在 X 轴上的移动距离。

• xAnimation:这是一个 DoubleAnimation 对象,它定义了动画的目标值和持续时间。在这个例子中,动画的目标值是鼠标点击的位置,持续时间是 4 秒。

• HandoffBehavior.SnapshotAndReplace:这是 HandoffBehavior 枚举的一个值,它定义了当新动画开始时,如何处理正在进行的动画。SnapshotAndReplace 表示新动画将替换旧动画,并从旧动画当前的值开始。

全部代码

xaml:

<Window x:Class="AnimationDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AnimationDemo"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<DockPanel>
<Border x:Name="_containerBorder" Background="Transparent">
<Ellipse x:Name="_interactiveEllipse"
Fill="Lime"
Stroke="Black"
StrokeThickness="2.0"
Width="25"
Height="25"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
</Border>
</DockPanel>
</Window>

cs:

using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes; namespace AnimationDemo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private readonly TranslateTransform _interactiveTranslateTransform;
public MainWindow()
{
InitializeComponent(); _interactiveTranslateTransform = new TranslateTransform(); _interactiveEllipse.RenderTransform =
_interactiveTranslateTransform; _containerBorder.MouseLeftButtonDown +=
border_mouseLeftButtonDown;
_containerBorder.MouseRightButtonDown +=
border_mouseRightButtonDown;
} private void border_mouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var clickPoint = Mouse.GetPosition(_containerBorder); // Set the target point so the center of the ellipse
// ends up at the clicked point.
var targetPoint = new Point
{
X = clickPoint.X - _interactiveEllipse.Width / 2,
Y = clickPoint.Y - _interactiveEllipse.Height / 2
}; // Animate to the target point.
var xAnimation =
new DoubleAnimation(targetPoint.X,
new Duration(TimeSpan.FromSeconds(4)));
_interactiveTranslateTransform.BeginAnimation(
TranslateTransform.XProperty, xAnimation, HandoffBehavior.SnapshotAndReplace); var yAnimation =
new DoubleAnimation(targetPoint.Y,
new Duration(TimeSpan.FromSeconds(4)));
_interactiveTranslateTransform.BeginAnimation(
TranslateTransform.YProperty, yAnimation, HandoffBehavior.SnapshotAndReplace); // Change the color of the ellipse.
_interactiveEllipse.Fill = Brushes.Lime;
} private void border_mouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
// Find the point where the use clicked.
var clickPoint = Mouse.GetPosition(_containerBorder); // Set the target point so the center of the ellipse
// ends up at the clicked point.
var targetPoint = new Point
{
X = clickPoint.X - _interactiveEllipse.Width / 2,
Y = clickPoint.Y - _interactiveEllipse.Height / 2
}; // Animate to the target point.
var xAnimation =
new DoubleAnimation(targetPoint.X,
new Duration(TimeSpan.FromSeconds(4)));
_interactiveTranslateTransform.BeginAnimation(
TranslateTransform.XProperty, xAnimation, HandoffBehavior.Compose); var yAnimation =
new DoubleAnimation(targetPoint.Y,
new Duration(TimeSpan.FromSeconds(4)));
_interactiveTranslateTransform.BeginAnimation(
TranslateTransform.YProperty, yAnimation, HandoffBehavior.Compose); // Change the color of the ellipse.
_interactiveEllipse.Fill = Brushes.Orange;
}
}
}

实现效果:

参考

1、Microsoft Learn:培养开拓职业生涯新机遇的技能

2、WPF-Samples/Animation/LocalAnimations/InteractiveAnimationExample.cs at main · microsoft/WPF-Samples (github.com)

WPF中动画教程(DoubleAnimation的基本使用)的更多相关文章

  1. WPF利用动画实现圆形进度条

    原文:WPF利用动画实现圆形进度条 这是我的第一篇随笔,最近因为工作需要,开始学习WPF相关技术,自己想实现以下圆形进度条的效果,逛了园子发现基本都是很久以前的文章,实现方式一般都是GDI实现的,想到 ...

  2. WPF中的动画——(三)时间线(TimeLine)

    WPF中的动画——(三)时间线(TimeLine) 时间线(TimeLine)表示时间段. 它提供的属性可以让控制该时间段的长度.开始时间.重复次数.该时间段内时间进度的快慢等等.在WPF中内置了如下 ...

  3. WPF异步载入图片,附带载入中动画

    原文:WPF异步载入图片,附带载入中动画 WPF异步载入图片,附带载入中动画 最近,在做一个WPF项目.项目中有一个需求,就是以列表的方式显示出项目图片.这些图片有的存在于互联网上,有的存在于本地磁盘 ...

  4. WPF中的DoubleAnimation

    原文:WPF中的DoubleAnimation WPF中的DoubleAnimation                                                         ...

  5. (转载)WPF中的动画——(一)基本概念

    http://www.cnblogs.com/TianFang/p/4050845.html WPF的一个特点就是支持动画,我们可以非常容易的实现漂亮大方的界面.首先,我们来复习一下动画的基本概念.计 ...

  6. WPF中的动画

    动画无疑是WPF中最吸引人的特色之一,其可以像Flash一样平滑地播放并与程序逻辑进行很好的交互.这里我们讨论一下故事板. 在WPF中我们采用Storyboard(故事板)的方式来编写动画,为了对St ...

  7. WPF中的动画——(一)基本概念

    WPF的一个特点就是支持动画,我们可以非常容易的实现漂亮大方的界面.首先,我们来复习一下动画的基本概念.计算机中的动画一般是定格动画,也称之为逐帧动画,它通过每帧不同的图像连续播放,从而欺骗眼和脑产生 ...

  8. 【WPF学习笔记】[转]周银辉之WPF中的动画 && 晓风影天之wpf动画——new PropertyPath属性链

    (一)WPF中的动画 动画无疑是WPF中最吸引人的特色之一,其可以像Flash一样平滑地播放并与程序逻辑进行很好的交互.这里我们讨论一下故事板. 在WPF中我们采用Storyboard(故事板)的方式 ...

  9. WPF中自动增加行(动画)的TextBox

    原文:WPF中自动增加行(动画)的TextBox WPF中自动增加行(动画)的TextBox WPF中的Textbox控件是可以自动换行的,只要设置TextWrapping属性为"Wrap& ...

  10. WPF中的PathAnimation(路径动画)

    原文:WPF中的PathAnimation(路径动画) WPF中的PathAnimation(路径动画)                                                 ...

随机推荐

  1. 责任链模式与spring容器的搭配应用

    背景 有个需求,原先只涉及到一种A情况设备的筛选,每次筛选会经过多个流程,比如先a功能,a功能通过再筛选b功能,然后再筛选c功能,以此类推.现在新增了另外一种B情况的筛选,B情况同样需要A情况的筛选流 ...

  2. win32 - 多字节下的中文字符打印到文本中

    #include <Windows.h> #include <stdio.h> #include <io.h> #include <fcntl.h> # ...

  3. 硬件开发笔记(十一):Altium Designer软件介绍、安装过程和打开pcb工程测试

    前言   前面做高速电路,选择是阿li狗,外围电路由于读者熟悉AD,使用使用ad比较顺手,非高速电路就使用AD了,其实AD也可以做高速电路,由于笔者从13年开始做硬是从AD9开始的,所以开始切入AD做 ...

  4. django学习第三天---django模板渲染,过滤器,反向循环 reversed,自定义标签和过滤器,模板继承

    django模板渲染 模板渲染,模板指的就是html文件,渲染指的就是字符串替换,将模板中的特殊符号替换成相关数据 基本语法 {{ 变量 }} {% 逻辑 %} 变量使用 示例 Views.py文件 ...

  5. win终端利器-Cmder的安装使用

    cmder 官网:https://cmder.app/ 安装 直接选择full版本下载,完成后解压即可 启动 直接双击Cmder.exe 如果每次都进入到 Cmder 解压目录双击 Cmder.exe ...

  6. 【Azure 服务总线】查看Service Bus中消息多次发送的日志信息,消息是否被重复消费

    问题描述 使用Service Bus,发现消息被重复消费.如果要查看某一条消息的具体消费情况,需要那些消息的属性呢? 问题解答 使用Azure Service Bus,当消费发送到服务端后,就会生产相 ...

  7. [Python] 协程学习过程

    开始 ​ 之前一直在做那个rProxy的项目,后来发现,服务端不用协程或者异步编程这样的手段是不行的,最主要的问题就是对于每个http请求都对应一个线程,这个开销非常大.对于一个网页而言,四五十个ht ...

  8. Windows NFS 真弱 → 中文乱码导致文件找不到

    开心一刻 正睡着觉,然后来了个电话 对方说:你好,方便面是吗 我愣了一下,以为是恶作剧 回了句:我不是,我是火腿肠! 就挂了电话 又躺了好一会,忽然琢磨过来...... 不对呀,她好像说的是:你好,方 ...

  9. CPNtools协议建模安全分析(一)

    本文根据最近整理的CPNtools论文和CPNtools官网上的说明,以及参照了乌克兰敖德萨 ---国家电信研究院运输和通信部关于   电信系统协议仿真关于CPNtools的学生讲义.基于此和和自己的 ...

  10. SSH原理与实践(一)

    主页 个人微信公众号:密码应用技术实战 个人博客园首页:https://www.cnblogs.com/informatics/ 引言 在日常开发和运维中,我们时常需要通过SSH登录远程主机,进行一些 ...