转换概述

本主题介绍如何使用 2D Transform 类旋转、缩放、移动(转换)和倾斜 FrameworkElement 对象。

什么是转换?

Transform 定义如何将点从一个坐标空间映射或转换到另一个坐标空间。 此映射由转换Matrix描述,该转换是由三行三列的Double值组成的集合。

注释

Windows Presentation Foundation (WPF) 使用行主矩阵。 向量表示为行向量,而不是列向量。

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

二维转换矩阵

X 轴 Y 轴 仿射变换
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) 为常见转换作提供以下 2D Transform 类:

班级 DESCRIPTION 示例: 图示
RotateTransform 按指定的 Angle值旋转元素。 旋转对象 旋转插图
ScaleTransform 根据指定的 ScaleXScaleY 数量缩放一个元素。 缩放元素 缩放图
SkewTransform 通过指定的AngleXAngleY使元素倾斜。 倾斜元素 倾斜插图
TranslateTransform 按指定 XY 数量移动元素(转换)。 转换元素 翻译插图

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

班级 DESCRIPTION 示例:
TransformGroup 将多个 TransformGroup 对象分组为一 Transform 个对象,然后可以应用于转换属性。 将多个转换应用于对象
MatrixTransform 创建其他 Transform 类未提供的自定义转换。 使用MatrixTransform时,您可以直接操控矩阵。 使用 MatrixTransform 创建自定义转换

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

通用转换属性

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

类型 转换属性
Brush TransformRelativeTransform
ContainerVisual Transform
DrawingGroup Transform
FrameworkElement RenderTransformLayoutTransform
Geometry Transform
TextEffect Transform
UIElement RenderTransform

转换和坐标系

转换对象时,不仅转换对象,还可以转换该对象所在的坐标空间。 默认情况下,转换以目标对象的坐标系的原点为中心:(0,0)。 唯一的例外是TranslateTransformTranslateTransform没有要设置的中心属性,因为无论变换效果在何处居中,效果都是相同的。

以下示例使用RotateTransformRectangle元素(一种FrameworkElement类型)绕其默认中心 (0, 0) 旋转 45 度。 下图显示了旋转的效果。

FrameworkElement 旋转 45 度左右 (0,0)
围绕点(0,0)旋转 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" />
    </Rectangle.RenderTransform>
  </Rectangle>
</Canvas>

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

下一个示例还使用RotateTransformRectangle元素旋转为45度。不过,这次CenterXCenterY属性被设置,使得RotateTransform的中心为(25, 25)。 下图显示了旋转的效果。

几何图形旋转约 45 度 (25, 25)
矩形元素围绕点 (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(框架元素)

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

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

  • RenderTransform – 修改元素外观的转换,但在布局处理完成后应用。 通过使用属性 RenderTransform 而不是 LayoutTransform 属性,可以获得性能优势。

应使用哪个属性? 由于它提供的性能优势,因此尽可能使用 RenderTransform 属性,尤其是在使用动画 Transform 对象时。 使用LayoutTransform属性进行缩放、旋转或倾斜时,如果您需要元素的父级调整为元素变换后的大小。 请注意,当它们与属性一起使用 LayoutTransform 时, TranslateTransform 对象似乎对元素没有影响。 这是因为布局系统在其处理过程中将转换后的元素返回到其原始位置。

有关 Windows Presentation Foundation 中布局的其他信息(WPF),请参阅 布局 概述。

示例:旋转框架元素 45度

下面的示例使用 RotateTransform 将按钮顺时针旋转 45 度。 该按钮包含在具有另外两个按钮的一个 StackPanel 中。

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

使用 RenderTransform 转换后的按钮
从左上角开始顺时针旋转 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">
      <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 进行转换的按钮,名为 graphicsmm_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>

对转换进行动画处理

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

以下示例利用 StoryboardDoubleAnimation 配合 RotateTransform 实现单击时 Button 原地旋转。

<Page 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://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>

有关完整示例,请参阅 二维转换示例。 有关动画的详细信息,请参阅 动画概述

可冻结特性

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

另请参阅