RenderTransformプロパティとLayoutTransformプロパティの違い

WPFではTransformクラスに様々な変形を行う機能が用意されていますので、大きくしたり回転させたりといったことが非常に簡単に実現できます。Transformクラスを継承したクラスとして、以下の4つのクラスが存在します。

クラス名 機能
ScaleTransform 縦、横の大きさの変形
SkewTransform 縦方向、横方向に斜めに変形
RotateTransform 回転
TranslateTransform 基準点からの縦方向、横方向への移動



これらのTransformを設定するプロパティとして、各UIElementにはRenderTransformとLayoutTransformの2つのプロパティが用意されています。

プロパティ名 機能
RenderTransform 内部のレイアウト処理が行われた後に適用されるため、レイアウトシステムは変更を認識できないが、パフォーマンスにすぐれている
LayoutTransform 内部のレイアウト処理が行われる前に適用されるため、レイアウトシステムが変形を認識できる



この2つのプロパティの大きな違いはレイアウトシステムが変形を認識するかしないかという部分なのですが、具体的にどういうことなのかは下記のXAMLコードをXamlPad等で実行して確認していただくと一目瞭然ですので、是非試してみてください。


XAML

<StackPanel
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <TextBlock TextAlignment="Center" Margin="24">RenderTransformプロパティ</TextBlock>
  <UniformGrid Rows="2" Columns="3">
    <TextBlock HorizontalAlignment="Center">回転</TextBlock>
    <TextBlock HorizontalAlignment="Center">スキュー Y軸</TextBlock>
    <TextBlock HorizontalAlignment="Center">縦方向のスケール</TextBlock>
    <Slider x:Name="RotationSlider" Maximum="360"/>
    <Slider x:Name="SkewYSlider" Maximum="180"/>
    <Slider x:Name="ScaleYSlider" Maximum="2" Value="1"/>
  </UniformGrid>
  <UniformGrid Rows="3" Columns="3">
    <Button Content="ボタン" />
    <Button Content="ボタン" />
    <Button Content="ボタン" />
    <Button Content="ボタン" />
    <Button Content="ボタン" RenderTransformOrigin="0.5 0.5" x:Name="RenderTransButton" >
      <Button.RenderTransform>
        <TransformGroup>
          <ScaleTransform ScaleY="{Binding Path=Value, ElementName=ScaleYSlider}"/>
          <SkewTransform AngleY="{Binding Path=Value, ElementName=SkewYSlider}"/>
          <RotateTransform Angle="{Binding Path=Value, ElementName=RotationSlider}"/>
        </TransformGroup>
      </Button.RenderTransform>
    </Button>
    <Button Content="ボタン" />
    <Button Content="ボタン" />
    <Button Content="ボタン" />
    <Button Content="ボタン" />
  </UniformGrid>
 
  <TextBlock TextAlignment="Center" Margin="24">LayoutTransformプロパティ</TextBlock>
  <UniformGrid Rows="2" Columns="3">
    <TextBlock HorizontalAlignment="Center">回転</TextBlock>
    <TextBlock HorizontalAlignment="Center">スキュー Y軸</TextBlock>
    <TextBlock HorizontalAlignment="Center">縦方向のスケール</TextBlock>
    <Slider x:Name="RotationSlider2" Maximum="360"/>
    <Slider x:Name="SkewYSlider2" Maximum="180"/>
    <Slider  x:Name="ScaleYSlider2" Maximum="2" Value="1"/>
  </UniformGrid>
  <UniformGrid Rows="3" Columns="3">
    <Button Content="ボタン" />
    <Button Content="ボタン" />
    <Button Content="ボタン" />
    <Button Content="ボタン" />
    <Button Content="ボタン" RenderTransformOrigin="0.5,0.5" x:Name="LayoutTransButton" >
      <Button.LayoutTransform>
        <TransformGroup>
          <ScaleTransform ScaleY="{Binding Path=Value, ElementName=ScaleYSlider2}"/>
          <SkewTransform AngleY="{Binding Path=Value, ElementName=SkewYSlider2}"/>
          <RotateTransform Angle="{Binding Path=Value, ElementName=RotationSlider2}"/>
        </TransformGroup>
      </Button.LayoutTransform>
    </Button>
    <Button Content="ボタン" />
    <Button Content="ボタン" />
    <Button Content="ボタン" />
    <Button Content="ボタン" />
  </UniformGrid>
</StackPanel>


XamlPadで実行した結果はこんな感じです。



LayoutTransformプロパティに設定したほうは、変形に合わせてUniformGridの各要素も変更されていることが分かります。