實現(xiàn)效果
今天以一個交互式小球的例子跟大家分享一下wpf動畫中DoubleAnimation
的基本使用。該小球會移動到我們鼠標左鍵或右鍵點擊的地方。
該示例的實現(xiàn)效果如下所示:

頁面設計
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的構造函數(shù)中賦值。
_interactiveTranslateTransform = new TranslateTransform();
TranslateTransform
是什么?有什么作用呢?

它的基本結構:
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 呈現(xiàn)位置的轉換信息。
_containerBorder.MouseLeftButtonDown +=
border_mouseLeftButtonDown;
_containerBorder.MouseRightButtonDown +=
border_mouseRightButtonDown;
這是在注冊_containerBorder
的鼠標左鍵點擊事件與鼠標右鍵點擊事件。


注意當Border這樣寫時,不會觸發(fā)鼠標點擊事件:
<Border x:Name="_containerBorder">
這是因為在 WPF 中,Border 控件的背景默認是透明的,這意味著它不會接收鼠標事件。當你設置了背景顏色后,Border 控件就會開始接收鼠標事件,因為它現(xiàn)在有了一個可見的背景。
如果你希望 Border 控件在沒有背景顏色的情況下也能接收鼠標事件,你可以將背景設置為透明色。這樣,雖然背景看起來是透明的,但它仍然會接收鼠標事件。
可以這樣設置:
<Border x:Name="_containerBorder" Background="Transparent">
鼠標點擊事件處理程序
以鼠標左鍵點擊事件處理程序為例,進行說明:
private void border_mouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var clickPoint = Mouse.GetPosition(_containerBorder);
var targetPoint = new Point
{
X = clickPoint.X - _interactiveEllipse.Width / 2,
Y = clickPoint.Y - _interactiveEllipse.Height / 2
};
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);
_interactiveEllipse.Fill = Brushes.Lime;
}
重點是:
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 中的一個類,它用于創(chuàng)建從一個 double 值到另一個 double 值的動畫。這個類是 AnimationTimeline 類的派生類,它可以用于任何接受 double 類型的依賴屬性。
DoubleAnimation 類有幾個重要的屬性:
? From:動畫的起始值。
? To:動畫的結束值。
? By:動畫的增量值,用于從 From 值增加或減少。
? Duration:動畫的持續(xù)時間。
? AutoReverse:一個布爾值,指示動畫是否在到達 To 值后反向運行回 From 值。
? RepeatBehavior:定義動畫的重復行為,例如,它可以設置為無限重復或重復特定的次數(shù)。
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 對象,它定義了動畫的目標值和持續(xù)時間。在這個例子中,動畫的目標值是鼠標點擊的位置,持續(xù)時間是 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
{
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);
var targetPoint = new Point
{
X = clickPoint.X - _interactiveEllipse.Width / 2,
Y = clickPoint.Y - _interactiveEllipse.Height / 2
};
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);
_interactiveEllipse.Fill = Brushes.Lime;
}
private void border_mouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
var clickPoint = Mouse.GetPosition(_containerBorder);
var targetPoint = new Point
{
X = clickPoint.X - _interactiveEllipse.Width / 2,
Y = clickPoint.Y - _interactiveEllipse.Height / 2
};
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);
_interactiveEllipse.Fill = Brushes.Orange;
}
}
}
實現(xiàn)效果:

轉自https://www.cnblogs.com/mingupupu/p/18108029
該文章在 2025/3/19 8:58:21 編輯過