Трансформация элементов

72

Свойства RenderTransform и RenderTransformOrigin не ограничиваются фигурами. Фактически, класс Shape наследует их от класса UIElement, а это означает, что они поддерживаются всеми элементами WPF, включая кнопки, текстовые поля, TextBlock, контейнеры компоновки, заполненные содержимым, и т.д. Невероятно, но можно поворачивать, искажать и масштабировать любую часть пользовательского интерфейса WPF (хотя в большинстве случаев этого делать и не стоит).

RenderTransform — не единственное свойство, касающееся трансформации, определенное в базовых классах WPF. В FrameworkElement также определено свойство LayoutTransform. Это свойство изменяет элемент тем же самым образом, но выполняет свою работу перед проходом компоновки. В результате требуется немного больше накладных расходов, но это оправдано, когда контейнер компоновки используется для обеспечения автоматического размещения группы элементов управления. (Классы фигур также включают свойство LayoutTransform, но с ним редко приходится работать, поскольку обычно фигуры размещаются специальным образом с использованием контейнера вроде Canvas вместо применения автоматической компоновки.)

Чтобы понять разницу, взгляните на рисунок из примера ниже, на котором изображено два контейнера StackPanel (представленных заштрихованными областями), которые содержат повернутую кнопку и нормальную кнопку. Повернутая кнопка в первом контейнере StackPanel использует подход RenderTransform. Панель StackPanel располагает две кнопки так, что первая из них позиционирована нормально, а поворот второй происходит непосредственно перед ее отображением. В результате повернутая кнопка перекрывает ту, что находится под ней. Во второй панели StackPanel повернутая кнопка применяет подход LayoutTransform. Контейнер StackPanel получает границы, необходимые для размещения повернутой кнопки, и располагает ее соответствующим образом.

<StackPanel>
    <StackPanel  Margin="25"  Background="LightYellow">
      <Button Padding="5" HorizontalAlignment="Left">
        <Button.RenderTransform>
          <RotateTransform Angle="35" CenterX="45" CenterY="5" />
        </Button.RenderTransform>
        <Button.Content>I'm rotated 35 degrees</Button.Content>
      </Button>
      <Button Padding="5" HorizontalAlignment="Left">I'm not</Button>
    </StackPanel>

    <StackPanel  Margin="25"  Background="LightYellow">
      <Button Padding="5" HorizontalAlignment="Left">
        <Button.LayoutTransform>
          <RotateTransform Angle="35" CenterX="45" CenterY="5" />
        </Button.LayoutTransform>
        <Button.Content>I'm rotated 35 degrees</Button.Content>
      </Button>
      <Button Padding="5" HorizontalAlignment="Left">I'm not</Button>
    </StackPanel>
  </StackPanel>

Существует несколько редких элементов, которые не могут быть трансформированы, потому что работа по их отображению не является встроенной в WPF. Примерами могут служить элемент WindowsFormsHost, который позволяет поместить элемент управления Windows Forms в окно WPF, а также элемент WebBrowser, который дает возможность отобразить HTML-содержимое.

До определенной степени элементы WPF остаются в неведении о том, что они были модифицированы, когда устанавливаются свойства LayoutTransform и RenderTransform. В частности, трансформации не затрагивают свойства ActualHeight и ActualWidth элемента, которые продолжают хранить его нетрансформированные размеры. Это часть того, как WPF обеспечивает продолжение работы потоковой компоновки и отступов с тем же поведением, даже если применяется одна или более трансформаций.

Пройди тесты
Лучший чат для C# программистов