Общие сведения о классах Transform

В этом разделе описано, как поворачивать, масштабировать, перемещать и наклонять объекты FrameworkElement с помощью классов двухмерных преобразований Transform.

Что такое преобразование?

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, его можно использовать для перемещения объекта на 100 единиц по оси X. Если изменить значение во втором столбце второй строки на 3, можно использовать его для растяжения объекта в три раза больше по сравнению с текущим размером. Если изменить оба значения, объект будет перемещен на 100 единиц по оси X, а его ширина будет увеличена в 3 раза. Так как Windows Presentation Foundation (WPF) поддерживает только аффинные преобразования, в правом столбце всегда указаны значения 0, 0, 1.

Хотя с помощью системы Windows Presentation Foundation (WPF) можно управлять значениями элементов матрицы напрямую, она также предоставляет несколько классов Transform, которые позволяют преобразовывать объект, не зная базовую структуру матрицы. Например, класс ScaleTransform позволяет масштабировать объект, указав его свойства ScaleX и ScaleY вместо изменения матрицы преобразования. Точно так же класс RotateTransform позволяет повернуть объект, просто задав его свойство Angle.

Классы преобразования

Windows Presentation Foundation (WPF) предоставляет следующие классы двухмерных преобразований Transform для распространенных операций преобразования:

Класс Description Пример Иллюстрация
RotateTransform Поворачивает элемент на указанный угол Angle. Вращение объекта Rotate illustration
ScaleTransform Масштабирует элемент в соответствии со значениями свойств ScaleX и ScaleY. Масштабирование элемента Scale illustration
SkewTransform Наклоняет элемент в соответствии со значениями углов AngleX и AngleY. Наклон элемента Skew illustration
TranslateTransform Перемещает элемент в соответствии со значениями свойств X и Y. Перемещение элемента Translate illustration

Для более сложных преобразований Windows Presentation Foundation (WPF) предоставляет два следующих класса:

Класс Description Пример
TransformGroup Группирует несколько объектов TransformGroup в один объект Transform, который затем можно применить к свойствам преобразования. Применение нескольких преобразований к объекту
MatrixTransform Создает пользовательские преобразования, которые не предоставляются другими классами Transform. При использовании MatrixTransform вы управляете матрицей напрямую. Использование MatrixTransform для создания пользовательских преобразований

Windows Presentation Foundation (WPF) также предоставляет трехмерные преобразования. Дополнительные сведения см. в описании класса Transform3D.

Общие свойства преобразования

Один из вариантов преобразования объекта — объявить соответствующий тип Transform и применить его к свойству преобразования объекта. У различных типов объектов есть различные типы свойств преобразования. В следующей таблице перечислены некоторые часто используемые типы Windows Presentation Foundation (WPF) и их свойства преобразования.

Тип Свойства преобразования
Brush Transform, RelativeTransform
ContainerVisual Transform
DrawingGroup Transform
FrameworkElement RenderTransform, LayoutTransform
Geometry Transform
TextEffect Transform
UIElement RenderTransform

Преобразования и системы координат

При преобразовании объекта преобразуется не только объект, но и пространство координат, в котором он существует. По умолчанию в качестве центральной точки для преобразования используется начало системы координат целевого объекта: (0, 0). Единственным исключением является TranslateTransform. У TranslateTransform нет свойств центра, так как преобразование имеет одинаковый результат независимо от положения центральной точки.

В следующем примере RotateTransform используется для поворота элемента Rectangle типа FrameworkElement на 45 градусов относительно центральной точки по умолчанию (0, 0). На следующем рисунке показан результат поворота.

A FrameworkElement rotated 45 degrees about (0,0)
Элемент Rectangle, повернутый на 45 градусов относительно точки (0,0)

<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). Классы RotateTransform, ScaleTransform и SkewTransform содержат свойства CenterX и CenterY, позволяющую указать точку, к которой применяется преобразование.

В следующем примере для поворота элемента Rectangle на 45 градусов так же используется RotateTransform; однако на этот раз свойства CenterX и CenterY установлены таким образом, что элемент RotateTransform поворачивается вокруг центральной точки (25, 25). На следующем рисунке показан результат поворота.

A Geometry rotated 45 degrees about (25, 25)
Элемент Rectangle, повернутый на 45 градусов относительно точки (25, 25)

<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. На рисунке ниже показан результат преобразования.

A button transformed using 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>

В следующем примере кнопка также поворачивается на 45 градусов по часовой стрелке с помощью RotateTransform, но наряду с этим для свойства RenderTransformOrigin кнопки устанавливается значение (0,5, 0,5). Значение свойства RenderTransformOrigin задается относительно размера кнопки. В результате кнопка поворачивается вокруг центра, а не вокруг левого верхнего угла. На рисунке ниже показан результат преобразования.

A button transformed about its center
Поворот на 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. При этом преобразование влияет на разметку кнопки, что приводит к запуску полного прохода системы разметки. Так как размер кнопки был изменен, то после поворота кнопки также изменяется ее положение. На рисунке ниже показан результат преобразования.

A button transformed using 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, примените анимацию совместимого типа к свойству, которое требуется анимировать.

В следующем примере с помощью раскадровки Storyboard, анимации DoubleAnimation и преобразования 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 наследуется от класса Freezable, он предоставляет ряд специальных возможностей: объекты Transform можно объявлять как ресурсы, разделять их между несколькими объектами, делать доступными только для чтения с целью повышения производительности, клонировать и делать потокобезопасными. Дополнительные сведения о различных функциях, предоставляемых объектами Freezable, см. в разделе Общие сведения об объектах класса Freezable.

См. также