RenderTransformとLayoutTransformについて
About
WPFではほとんどのコントロール(Window以外?)を拡大縮小したり回転したりして変形することができます。変形方法には2つあり、RenderTransformを利用する場合と、LayoutTransformを利用する場合の2つです。ここではこれらの2つについて扱います。
- このページの多くの内容は次のMSDNのページから公式見解が得られます。
RenderTransformとLayoutTransformの違い
RenderTransformもLayoutTransformも扱うことのできるTansform(ScaleやSkew)は共通ですが、それぞれ次のように異なります。
- RenderTransform
- レイアウト処理が確定した後に変形が適用される。
- LayoutTransform
- レイアウト処理が確定する前に変形される。
まずレイアウト処理とは、GridやStackPanel、DockPanelなど、複数のコンポーネントが互いに干渉するような場合、例えばWidth=Autoなどが設定される場合に、実行処理時に実際の幅(ActualWidth/Height)が決定される処理です。
このレイアウト処理が実行結果にどう表れるかというと、例えばコンポーネントを回転した後に幅を取るか、コンポーネントの幅を取った後に回転するか、の違いです。前者の場合は隣り合うコンポーネントと重なりませんが、後者はコンポーネント同士が重なってしまう可能性があります。
またコンポーネントの幅を取り直す関係上、LayoutTransformの方が、パフォーマンスが悪いようです。どの程度の差が出るかは定かではありませんが、フレキシブルにレイアウトが決まるコンポーネント数が多いほど影響を受けやすいでしょう(Width/HeightがAuto/*だったりflowレイアウトだったり)。
適切なTransformとその変換Property
LayoutTransformを設定したのに変化がない、なんて場合があります。知っておかなければならないのは、LayoutTransformは設定されたTranslateTransformを無視します。よってTranslateTransformを利用したい場合にはRenderTransformを利用する必要があります。
またFrameworkElementはRenderTransformプロパティもLayoutTransformプロパティも用意されていますが、UIElementにはRenderTransformのみが用意されています。実装形態は UIElement > FrameworkElement となっているので、キャストが必要な場合には注意する必要があります。
例えばCanvasのChildプロパティから取得できるElementはUIElementです。FrameworkElementにキャストできる保証はありませんので、実質的にはRenderTransformを利用するのが無難になります。キャストのチェックをすれば解決できますがスマートではないと思われます。とは言えほとんどの場合にこのような実装形態はとられないでしょう。インタラクティブでゲームチックなアプリケーションを作る場合のみ考慮されるかもしれません。