实现效果

今天以一个交互式小球的例子跟大家分享一下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. jupyter环境变量配置与启动

    一.jupyter基础知识 1.基本概念 jupyter是基于网页的用于交互计算的应用程序.其可被应用于全过程计算:开发.文档编写.运行代码和展示结果. 编程时具有语法高亮,缩进,tab补全的功能. ...

  2. 【LeetCode二叉树#11】最大二叉树(构造二叉树)

    最大二叉树 力扣题目地址(opens new window) 给定一个不含重复元素的整数数组.一个以此数组构建的最大二叉树定义如下: 二叉树的根是数组中的最大元素. 左子树是通过数组中最大值左边部分构 ...

  3. 【Azure K8S】演示修复因AKS密钥过期而导致创建服务不成功的问题(The provided client secret keys for app ****** are expired)

    问题描述 在Azure Kubernetes 服务中,创建一个Internal Load Balancer服务,使用以下yaml内容: internallb.yaml apiVersion: v1 k ...

  4. 4、zookeeper的事件监听机制

    watcher概念 https://zookeeper.apache.org/doc/r3.4.14/zookeeperProgrammers.html#sc_WatchRememberThese z ...

  5. 用几张图实战讲解MySQL主从复制

    本文分享自华为云社区<结合实战,我为MySQL主从复制总结了几张图!>,作者: 冰 河. MySQL官方文档 MySQL 主从复制官方文档链接地址如下所示: http://dev.mysq ...

  6. liunx 进阶技术

    以下命令非学习阶段常用,在工作设汲到用liunx操作的时候以下必然要用,所以记录整理一下 关掉服务器所有java程序使用命令 pkill java 查看当前运行java服务 ps -ef | grep ...

  7. 软件发布时 生成发布日志文件 单点登录 getGitInfo.bat

    需求 每次发包的时候,前端是3个包,如果后期出现问题,不好回查 所以把当前项目的git信息记录下来 以便回查 第一次手动写了下,发现比较麻烦,所以写个脚本,每次发布的时候 运行下即可 上代码 软件发布 ...

  8. Pod中断预算 PodDisruptionBudget(PDB)

    PodDisruptionBudget(PDB)是Kubernetes中的一个资源对象,用于确保在进行维护.升级或其他操作时,系统中的Pod不会被意外中断或终止.PDB提供了一种机制,通过限制在给定时 ...

  9. 【预训练语言模型】使用Transformers库进行GPT2预训练

    基于 HuggingFace的Transformer库,在Colab或Kaggle进行预训练. 本教程提供:英文数据集wikitext-2和代码数据集的预训练. 注:可以自行上传数据集进行训练 目的: ...

  10. .net core 多线程下使用 Random 会出现bug

    .net core 多线程下使用 Random 会出现的bug 先看原文: Working with System.Random and threads safely in .NET Core and ...