共用方式為


轉換概觀

了解如何藉由變更 UI 中元素的相對座標系統,在 Windows 執行階段API 中使用轉換。 這可用來調整個別 XAML 元素的外觀,例如縮放、旋轉或轉換 x-y 空間中的位置。

什麼是轉換?

轉換定義如何將點從一個座標空間對應 (或轉換) 至另一個座標空間。 當將轉換套用至 UI 元素時,它會變更該 UI 元素作為 UI 的一部分在螢幕上的呈現方式。

轉換可分為四大類:平移、旋轉、縮放和扭曲 (或傾斜)。 為了使用圖形 API 來變更 UI 元素的外觀,通常最簡單的方式是建立一次只定義一個作業的轉換。 因此,Windows 執行階段為每個轉換分類定義離散類別:

其中,對於 UI 情境,您可能最常使用 TranslateTransformScaleTransform

您可以將不同的轉換結合使用,而有兩個 Windows 執行階段類別支援這麼做:CompositeTransformTransformGroup。 在 CompositeTransform 中,轉換會依下列順序套用:縮放、扭曲、旋轉、平移。 如果您想要以不同的順序套用轉換,請使用 TransformGroup,而不是 CompositeTransform。 如需詳細資訊,請參閱 CompositeTransform

轉換與配置

在 XAML 版面配置中,轉換會在版面配置階段完成之後套用,因此在套用轉換之前,已進行可用空間計算和其他版面配置決策。 由於版面配置是第一位,所以如果您 Grid 單元格中的元素或在版面配置期間分配空間的類似版面配置容器中的元素,有時會取得非預期的結果。 轉換後的元素可能會出現截斷或模糊的情況,因為它在試圖繪製到在其父容器內劃分空間時,未計算轉換後維度的區域。 您可能需要試驗轉換結果,然後調整一些設定。 例如,您可能需要變更 Center 屬性或宣告版面配置空間的固定像素度量,以確保父系分配足夠的空間,而不是依賴調適型版面配置和星號調整大小。

遷移注意事項:Windows Presentation Foundation (WPF) 已有在版面配置階段前先套用轉換的 LayoutTransform 屬性。 但是 Windows 執行階段 XAML 不支援 LayoutTransform 屬性。 (Microsoft Silverlight 也沒有此屬性。)

或者,Windows 社區工具組會提供 LayoutTransformControl,可將矩陣轉換應用於應用程式的任何 FrameworkElement。

將轉換套用到 UI 元素

當您對物件套用轉換時,通常會設定 UIElement.RenderTransform 屬性。 設定此屬性並不會逐個像素地變更物件。 此屬性的真正作用是在該物件所在的局部座標空間內套用轉換。 然後,轉譯邏輯和作業 (配置後) 會轉譯組合的座標空間,使其看起來像物件已變更外觀,也可能是其版面配置位置 (如果已套用 TranslateTransform)。

根據預設,每個轉譯轉換都會以目標物件之局部座標系統的原點 (0,0) 為中心。 唯一的例外狀況是 TranslateTransform,它沒有要設定的中心屬性,因為無論在何處居中,平移效果都是相同的。 但其他轉換均具有設定 CenterXCenterY 值的屬性。

每當您以 UIElement.RenderTransform 來使用轉換時,請記住在會影響轉換行為的 UIElement 上有另一個屬性:RenderTransformOriginRenderTransformOrigin 宣告的是,整個轉換是否應套用於元素的預設 (0,0) 點,或應套用於該元素的相對座標空間內的某個其他原點。 對於一般元素,(0,0) 會將轉換放置在左上角。 根據您想要的效果,您可以選擇變更 RenderTransformOrigin,而不是調整轉換上的 CenterXCenterY 值。 請注意,如果您同時套用 RenderTransformOriginCenterX / CenterY 值,結果可能會非常混亂,尤其是在您對任何值進行動畫處理時。

出於點擊測試目的,套用轉換的物件會繼續以預期的方式響應輸入,使其在 x-y 空間中的視覺外觀一致。 例如,如果您使用 TranslateTransform 在 UI 中橫向移動 Rectangle 400 像素,則當使用者按下 Rectangle 以視覺方式顯示之點時,Rectangle 會回應 PointerPressed 事件。 如果使用者按下 Rectangle 在平移之前所在的區域,您不會收到錯誤事件。 對於影響點擊測試的任何 z-index 考慮因素,套用轉換並無任何差異; 控制哪個元素處理 x-y 空間中某點的輸入事件的 z-index 仍會使用容器中宣告的子順序進行評估。 此順序通常與在 XAML 中宣告元素的順序相同,但對於 Canvas 物件的子元素,您可以透過將 Canvas.ZIndex 附加屬性套用至子元素來調整順序。

其他轉換屬性

以動畫顯示轉換

Transform 物件可以用動畫顯示。 若要建立 Transform 的動畫,請將相容類型的動畫套用至您希望建立動畫的屬性。 這通常表示您正在使用 DoubleAnimationDoubleAnimationUsingKeyFrames 物件來定義動畫,因為所有轉換屬性都是 Double 類型。 影響用於 UIElement.RenderTransform 值之轉換的動畫不視為相依動畫,即使它們具有非零持續時間。 如需相依動畫的詳細資訊,請參閱分鏡動畫

如果您對屬性進行動畫處理以在淨視覺外觀方面產生類似於轉換的效果 (例如,對 FrameworkElement寬度高度進行動畫處理而不是套用 TranslateTransform),則此類動畫幾乎總是被視為從屬動畫。 您必須啟用動畫,而且動畫可能會有顯著的效能問題,尤其是當您嘗試在該物件進行動畫處理時,支援使用者互動。 因此,最好使用轉換並對其進行動畫處理,而不是對動畫被視為從屬動畫的任何其他屬性進行動畫處理。

若要以轉換為目標,必須有一個現有的 Transform 作為 RenderTransform 的值。 通常,您會在初始 XAML 中放置適當轉換類型的元素,有時不會在該轉換上設定任何屬性。

您通常會使用間接定位技術,將動畫套用到轉換的屬性。 如需間接目標語法的詳細資訊,請參閱分鏡動畫屬性路徑語法

控制項的預設樣式有時會將轉換的動畫定義為其視覺狀態行為的一部分。 例如,ProgressRing 的視覺狀態會使用動畫 RotateTransform 值來「旋轉」環形中的點。

以下是如何建立轉換動畫的簡單範例。 在本例中,其會對 RotateTransform角度進行動畫處理,以圍繞其視覺中心旋轉矩形。 此範例命名了 RotateTransform,因此不需要間接動畫定位,但您也可以不命名轉換,命名轉換所套用到的元素,並使用間接定位,例如 (UIElement.RenderTransform).(RotateTransform.Angle)

<StackPanel Margin="15">
  <StackPanel.Resources>
    <Storyboard x:Name="myStoryboard">
      <DoubleAnimation
       Storyboard.TargetName="myTransform"
       Storyboard.TargetProperty="Angle"
       From="0" To="360" Duration="0:0:5" 
       RepeatBehavior="Forever" />
    </Storyboard>
  </StackPanel.Resources>
  <Rectangle Width="50" Height="50" Fill="RoyalBlue"
   PointerPressed="StartAnimation">
    <Rectangle.RenderTransform>
      <RotateTransform x:Name="myTransform" Angle="45" CenterX="25" CenterY="25" />
    </Rectangle.RenderTransform>
  </Rectangle>
</StackPanel>
void StartAnimation (object sender, RoutedEventArgs e) {
    myStoryboard.Begin();
}

說明執行階段的參考座標框架

UIElement 有一個名為 TransformToVisual, 的方法,這個方法可以產生將兩個 UI 元素的參考座標框架相互關聯的 Transform。 如果您將根視覺物件作為第一個參數傳遞,則可以使用它來將元素與應用程式的預設參考座標系進行比較。 如果您從不同的元素捕獲了輸入事件,或者您嘗試預測版面配置行為而不實際要求版面配置傳遞,那麼這會很有用。

從指標事件取得的事件資料可讓您存取 GetCurrentPoint 方法,您可以在其中指定 relativeTo 參數來變更特定元素的參考座標框架,而不是應用程式預設值。 此方法只是在內部套用平移轉換,並在建立傳回的 PointerPoint 物件時為您轉換 x-y 座標資料。

從數學觀點描述轉換

轉換可以用轉換矩陣來描述。 3×3 矩陣可用來描述二維 x-y 平面中的轉換。 仿射轉換矩陣可以乘以形成任意數目的線性轉換,例如旋轉和扭曲 (傾斜),然後進行平移。 仿射轉換矩陣的最後一列等於 (0, 0, 1),因此您只需指定數學描述中前兩列的成員。

如果您具有數學背景或熟悉也使用矩陣來描述座標空間轉換的圖形程式技術,則轉換的數學描述可能對您有用。 有一個 Transform 衍生類別可讓您以轉換的 3×3 矩陣來直接表示該轉換:MatrixTransformMatrixTransform 具有 Matrix 屬性,其結構有六個屬性:M11M12M21M22OffsetXOffsetY。 每個 Matrix 屬性都會使用 Double 值,並對應於仿射轉換矩陣的六個相關值(欄 1 和欄 2)。

欄 1 欄 2 欄 3
M11 M12 0
M21 M22 0
OffsetX OffsetY 1

您可以使用 TranslateTransformScaleTransformRotateTransformSkewTransform 物件來描述的任何轉換,可以透過具有 Matrix 值的 MatrixTransform 來描述。 但您通常只使用 TranslateTransform 和其他類別,因為這些轉換類別的屬性比在 Matrix 中設定向量元件更容易概念化。 為轉換的離散屬性設定動畫也很容易; Matrix 實際上是一個結構體而不是 DependencyObject,因此它不能支援動畫單一值。

一些可讓您套用轉換作業的 XAML 設計工具會將結果序列化為 MatrixTransform。 在這種情況下,最好再次使用相同的設計工具來變更轉換效果並再次序列化 XAML,而不是嘗試直接在 XAML 中自行操作 Matrix 值。

3D 轉換

在 Windows 10 中,XAML 引入了一個新屬性 UIElement.Transform3D,可用來透過 UI 建立 3D 效果。 若要這樣做,請使用 PerspectiveTransform3D 將共用 3D 透視圖或「相機」新增至場景中,然後使用 CompositeTransform3D 轉換 3D 空間中的元素,就像使用 CompositeTransform 一樣。 如需如何實作 3D 轉換的討論,請參閱 UIElement.Transform3D

對於僅適用於單一物件的較簡單 3D 效果,可以使用 UIElement.Projection 屬性。 使用 PlaneProjection 作為此屬性的值相當於對元素套用固定透視轉換和一個或多個 3D 轉換。 XAML UI 的 3D 透視效果中更詳細地描述了這種類型的轉換。