变换概述

本主题描述如何使用 2-D Transform 类来旋转、按比例缩放、移动(平移)和扭曲 FrameworkElement 对象。

本主题包括下列各节。

  • 什么是变换?
  • 变换类
  • 常见变换属性
  • 变换和坐标系
  • 变换 FrameworkElement
  • 示例:将 FrameworkElement 旋转 45 度
  • 对变换进行动画处理
  • Freezable 功能
  • 相关主题

什么是变换?

Transform 定义如何将一个坐标空间中的点映射或变换到另一个坐标空间。 此映射由变换 Matrix(一个三行三列的 Double 值集合)来描述。

注意注意

Windows Presentation Foundation (WPF) 使用行优先矩阵。矢量用行矢量(而不是列矢量)表示。

下表显示了 WPF 矩阵的结构。

二维变换矩阵

M11

默认值:1.0

M12

默认值:0.0

0.0

M21

默认值:0.0

M22

默认值:1.0

0.0

OffsetX

默认值:0.0

OffsetY

默认值:0.0

1.0

通过处理矩阵值,您可以旋转、按比例缩放、扭曲和移动(平移)对象。 例如,如果将第三行第一列中的值(OffsetX 值)更改为 100,则可以使用它将对象沿 x 轴移动 100 个单位。 如果将第二行第二列中的值更改为 3,您可以使用它将对象拉伸为其当前高度的三倍。 如果同时更改两个值,则可将对象沿 x 轴移动 100 个单位并将其高度拉伸 3 倍。 由于 Windows Presentation Foundation (WPF) 仅支持仿射变换,因此右边列中的值始终为 0、0、1。

尽管 Windows Presentation Foundation (WPF) 使您能够直接处理矩阵值,但它还提供了许多 Transform 类,您可以使用这些类来变换对象,而无需了解基础矩阵结构的配置方式。 例如,利用 ScaleTransform 类,您可以通过设置对象的 ScaleXScaleY 属性来按比例缩放对象,而不用处理变换矩阵。 同样,利用 RotateTransform 类,您只需通过设置对象的 Angle 属性即可旋转对象。

变换类

Windows Presentation Foundation (WPF) 为常见变换操作提供了以下 2-D Transform 类:

说明

示例

图示

RotateTransform

按指定的 Angle 旋转元素。

如何:旋转对象

旋转图

ScaleTransform

按指定的 ScaleXScaleY 量按比例缩放元素。

如何:缩放元素

缩放图

SkewTransform

按指定的 AngleXAngleY 量扭曲元素。

如何:使元素扭曲

扭曲图

TranslateTransform

按指定的 XY 量移动(平移)元素。

如何:平移元素

平移图

为了创建更复杂的变换,Windows Presentation Foundation (WPF) 提供了如下两个类:

说明

示例

TransformGroup

将多个 TransformGroup 对象组合为可以随后应用于变换属性的单一 Transform

如何:向对象应用多个变换

MatrixTransform

创建其他 Transform 类未提供的自定义变换。 在使用 MatrixTransform 时,将直接处理矩阵。

如何:使用 MatrixTransform 创建自定义变换

Windows Presentation Foundation (WPF) 也提供3-D变换。 有关更多信息,请参见 Transform3D 类。

常见变换属性

变换对象的一种方法是声明适当的 Transform 类型,并将其应用于对象的变换属性。 不同类型的对象具有不同类型的变换属性。 下表列出了若干常用的 Windows Presentation Foundation (WPF) 类型及其变换属性。

类型

变换属性

Brush

Transform, RelativeTransform

ContainerVisual

Transform

DrawingGroup

Transform

FrameworkElement

RenderTransform, LayoutTransform

Geometry

Transform

TextEffect

Transform

UIElement

RenderTransform

变换和坐标系

在变换对象时,您不仅仅是变换对象,您变换的是对象所在的坐标系。 默认情况下,变换将以目标对象坐标系的原点 (0,0) 为中心进行。 唯一的例外是 TranslateTransformTranslateTransform 没有要设置的中心属性,因为不管以何处为中心,平移效果都相同。

下面的示例使用 RotateTransform,围绕其默认中心 (0, 0) 将 Rectangle 元素(一种 FrameworkElement)旋转 45 度。 下图显示了旋转的效果。

围绕点 (0,0) 旋转 45 度的矩形元素

围绕 (0,0) 旋转 45 度的 FrameworkElement

<Canvas Width="200" Height="200">
  <Rectangle 
    Canvas.Left="100" Canvas.Top="100"
    Width="50" Height="50" 
    Fill="RoyalBlue" Opacity="1.0">
    <Rectangle.RenderTransform>
      <RotateTransform Angle="45" />
    </Rectangle.RenderTransform>
  </Rectangle>
</Canvas>

默认情况下,元素将围绕其左上角 (0, 0) 旋转。 RotateTransformScaleTransformSkewTransform 类提供 CenterX 和 CenterY 属性,可以利用这些属性来指定变换的应用点。

下一个示例也使用 RotateTransformRectangle 元素旋转 45 度;但是,这一次设置了 CenterXCenterY 属性,因此 RotateTransform 的中心为 (25, 25)。 下图显示了旋转的效果。

围绕点 (25, 25) 旋转 45 度的矩形元素

围绕 (25, 25) 旋转 45 度的几何图形

<Canvas Width="200" Height="200">
  <Rectangle 
    Canvas.Left="100" Canvas.Top="100"
    Width="50" Height="50" 
    Fill="RoyalBlue" Opacity="1.0">
    <Rectangle.RenderTransform>
      <RotateTransform Angle="45" CenterX="25" CenterY="25" />
    </Rectangle.RenderTransform>
  </Rectangle>
</Canvas>

变换 FrameworkElement

若要将变换应用于 FrameworkElement,请创建 Transform 并将其应用于 FrameworkElement 类提供的两个属性之一:

  • LayoutTransform — 在布局处理过程之前应用的变换。 应用了变换后,布局系统将处理元素的变换后大小和位置。

  • RenderTransform — 修改元素的外观但在布局处理过程完成之后应用的变换。 通过使用 RenderTransform 属性(而不是 LayoutTransform 属性),您可以使性能得到优化。

应使用哪个属性? 由于 RenderTransform 属性能够使性能得到优化,因此请尽可能使用该属性,特别是在使用带有动画效果的 Transform 对象时。 在按比例缩放、旋转或扭曲时使用 LayoutTransform 属性,并且,您需要元素的父项适应元素的变换后大小。 请注意,将 TranslateTransform 对象与 LayoutTransform 属性一起使用时,这些对象似乎对元素没有影响。 这是因为布局系统在处理过程中会使平移的元素回到其原始位置。

有关 Windows Presentation Foundation (WPF) 中的布局的附加信息,请参见布局系统概述。

示例:将 FrameworkElement 旋转 45 度

下面的示例使用 RotateTransform 将按钮沿顺时针方向旋转 45 度。 该按钮包含在具有两个其他按钮的 StackPanel 中。

默认情况下,RotateTransform 围绕点 (0, 0) 旋转。 由于示例未指定中心值,因此按钮将围绕点 (0, 0)(即按钮的左上角)旋转。 RotateTransform 应用于 RenderTransform 属性。 下图显示了变换的效果。

从左上角沿顺时针方向旋转 45 度

使用 RenderTransform 变换的按钮

<Border Margin="30" 
  HorizontalAlignment="Left" VerticalAlignment="Top"
  BorderBrush="Black" BorderThickness="1" >
  <StackPanel Orientation="Vertical">
    <Button Content="A Button" Opacity="1" />
    <Button Content="Rotated Button">
      <Button.RenderTransform>
        <RotateTransform Angle="45" />
      </Button.RenderTransform>
    </Button>
    <Button Content="A Button" Opacity="1" />
  </StackPanel>
</Border>

下一个示例也使用 RotateTransform 将按钮沿顺时针方向旋转 45 度,但它同时将按钮的 RenderTransformOrigin 设置为 (0.5, 0.5)。 RenderTransformOrigin 属性的值与按钮的大小相关。 因此,将在按钮的中心(而不是其左上角)应用旋转。 下图显示了变换的效果。

围绕中心沿顺时针方向旋转 45 度

围绕中心变换的按钮

<Border Margin="30"   
  HorizontalAlignment="Left" VerticalAlignment="Top"
  BorderBrush="Black" BorderThickness="1">
  <StackPanel Orientation="Vertical">
    <Button Content="A Button" Opacity="1" />
    <Button Content="Rotated Button"
      RenderTransformOrigin="0.5,0.5">
      <Button.RenderTransform>
        <RotateTransform Angle="45" />
      </Button.RenderTransform>
    </Button>
    <Button Content="A Button" Opacity="1" />
  </StackPanel>
</Border>

下面的示例使用 LayoutTransform 属性(而不是 RenderTransform 属性)来旋转按钮。 这样会使变换影响按钮的布局,从而触发布局系统的全面处理过程。 因此,将会旋转按钮,然后重新定位按钮,因为按钮大小发生了变化。 下图显示了变换的效果。

用于旋转按钮的 LayoutTransform

使用 LayoutTransform 变换的按钮

<Border Margin="30"   
 HorizontalAlignment="Left" VerticalAlignment="Top"
 BorderBrush="Black" BorderThickness="1">
  <StackPanel Orientation="Vertical">

    <Button Content="A Button" Opacity="1" />   
    <Button Content="Rotated Button">
      <Button.LayoutTransform>
        <RotateTransform Angle="45"  />
      </Button.LayoutTransform>
    </Button>   
    <Button Content="A Button" Opacity="1" />
  </StackPanel>
</Border>

对变换进行动画处理

由于 Transform 类继承自 Animatable 类,因此可以对它们进行动画处理。 若要对 Transform 进行动画处理,请将类型兼容的动画应用于想要进行动画处理的属性。

下面的示例将 StoryboardDoubleAnimationRotateTransform 一起使用,以便在单击 Button 时使其旋转到位。

<Page 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  Title="Button Animated RotateTransform Example"
  Background="White" Margin="50">
  <StackPanel>



    <Button Content="A Button"
      RenderTransformOrigin="0.5,0.5">
      <Button.RenderTransform>
        <RotateTransform x:Name="AnimatedRotateTransform" Angle="0" />
      </Button.RenderTransform>
      <Button.Triggers>
        <EventTrigger RoutedEvent="Button.Click">
          <BeginStoryboard>
            <Storyboard>
              <DoubleAnimation 
                Storyboard.TargetName="AnimatedRotateTransform"
                Storyboard.TargetProperty="Angle" 
                To="360" Duration="0:0:1" FillBehavior="Stop" />
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
      </Button.Triggers>
    </Button>

  </StackPanel>
</Page>

有关完整示例,请参见 2-D Transforms Sample(二维转换示例)。 有关动画的更多信息,请参见动画概述

Freezable 功能

由于 Transform 类继承自 Freezable 类,因此它提供了多种特殊功能:Transform 对象可声明为资源、在多个对象之间共享、设为只读以提高性能、进行克隆以及设为线程安全。 有关 Freezable 对象提供的不同功能的更多信息,请参见Freezable 对象概述

请参见

参考

Transform

Matrix

其他资源

变换帮助主题

2-D Transforms Sample