Übersicht über Transformationen

Erfahren Sie, wie Sie Transformationen in der Windows-Runtime-API verwenden, indem Sie die relativen Koordinatensysteme von Elementen in der Benutzeroberfläche ändern. Dies kann verwendet werden, um die Darstellung einzelner XAML-Elemente anzupassen, z. B. Skalieren, Drehen oder Transformieren der Position im X-Y-Raum.

Was ist eine Transformation?

Eine Transformation definiert, wie Punkte von einem Koordinatensystem zu einem anderen Koordinatensystem zugeordnet oder transformiert werden. Wenn eine Transformation auf ein UI-Element angewendet wird, ändert sie, wie dieses UI-Element als Teil der Benutzeroberfläche auf dem Bildschirm gerendert wird.

Stellen Sie sich Transformationen in vier allgemeinen Klassifizierungen vor: Verschiebung, Drehung, Skalierung und Schrägstellung (oder Scherung). Für die Verwendung von Grafik-APIs zum Ändern der Darstellung von UI-Elementen ist es in der Regel am einfachsten, Transformationen zu erstellen, die jeweils nur einen Vorgang definieren. Daher definiert die Windows-Runtime eine diskrete Klasse für jede dieser Transformationsklassifizierungen:

Davon verwenden Sie wahrscheinlich TranslateTransform und ScaleTransform am häufigsten für UI-Szenarien.

Sie können Transformationen kombinieren, und es gibt zwei Windows-Runtime-Klassen, die folgendes unterstützen: CompositeTransform und TransformGroup. In einem CompositeTransform-werden Transformationen in dieser Reihenfolge angewendet: Skalierung, Schrägstellung, Rotation, Translation. Verwenden Sie TransformGroup anstelle von CompositeTransform , wenn die Transformationen in einer anderen Reihenfolge angewendet werden sollen. Weitere Informationen finden Sie unter CompositeTransform.

Transformationen und Layouts

Im XAML-Layout werden Transformationen angewendet, nachdem der Layoutdurchlauf abgeschlossen ist, sodass Berechnungen des verfügbaren Raums und andere Layoutentscheidungen bereits getroffen wurden, bevor die Transformationen angewendet werden. Da das Layout zuerst erfolgt, können Sie manchmal unerwartete Ergebnisse erhalten, wenn Sie Elemente transformieren, die sich in einer Grid- Zelle oder einem ähnlichen Layoutcontainer befinden, der während des Layouts Platz zuweist. Das transformierte Element wird möglicherweise abgeschnitten oder verdeckt dargestellt, weil es versucht, in einen Bereich zu rendern, der beim Aufteilen des Raums innerhalb des übergeordneten Containers die Dimensionen nach der Transformation nicht berücksichtigt hat. Möglicherweise müssen Sie mit den Transformationsergebnissen experimentieren und einige Einstellungen anpassen. Anstatt beispielsweise auf adaptives Layout und Stern-Größenanpassung zu vertrauen, müssen Sie möglicherweise die Center-Eigenschaften ändern oder feste Pixelmaße für den Layoutbereich deklarieren, um sicherzustellen, dass das übergeordnete Element genügend Platz zuweist.

Migrationshinweis: Windows Presentation Foundation (WPF) verfügte über eine LayoutTransform--Eigenschaft, die transformationen vor dem Layoutdurchlauf angewendet hat. Windows-Runtime-XAML unterstützt jedoch keine LayoutTransform--Eigenschaft. (Microsoft Silverlight hatte diese Eigenschaft ebenfalls nicht.)

Tipp

Alternativ stellt das Windows Community Toolkit die LayoutTransformControl- bereit, die Matrixtransformationen auf jedes FrameworkElement Ihrer Anwendung anwendet.

Anwenden einer Transformation auf ein UI-Element

Wenn Sie eine Transformation auf ein Objekt anwenden, setzen Sie in der Regel die Eigenschaft UIElement.RenderTransformfest. Das Festlegen dieser Eigenschaft ändert das Objekt nicht buchstäblich Pixel für Pixel. Was die Eigenschaft tatsächlich tut, ist, die Transformation im lokalen Koordinatenraum anzuwenden, in dem sich das Objekt befindet. Anschließend rendert die Renderinglogik und der Vorgang (post-layout) die kombinierten Koordinatenräume, sodass es so aussieht, als hätte sich die Darstellung des Objekts geändert und möglicherweise auch seine Layoutposition, falls TranslateTransform angewendet wurde.

Standardmäßig wird jede Rendertransformation am Ursprung des lokalen Koordinatensystems des Zielobjekts (0,0) zentriert. Die einzige Ausnahme ist eine TranslateTransform-, die keine zentrierten Eigenschaften festlegen kann, da der Übersetzungseffekt unabhängig davon, wo er zentriert ist, identisch ist. Die anderen Transformationen weisen jedoch Eigenschaften auf, die CenterX- und CenterY--Werte festlegen.

Wenn Sie Transformationen mit UIElement.RenderTransformverwenden, denken Sie daran, dass es bei UIElement eine andere Eigenschaft gibt, die das Verhalten der Transformation beeinflusst: RenderTransformOrigin. Was RenderTransformOrigin deklariert, ist, ob die gesamte Transformation auf den Standardpunkt (0,0) eines Elements oder auf einen anderen Ursprungspunkt innerhalb des relativen Koordinatenbereichs dieses Elements angewendet werden soll. Bei typischen Elementen platziert (0,0) die Transformation in die obere linke Ecke. Je nach gewünschtem Effekt können Sie RenderTransformOrigin- ändern, anstatt die CenterX- und CenterY- Werte für Transformationen anzupassen. Beachten Sie, dass die Ergebnisse ziemlich verwirrend sein können, wenn Sie sowohl die RenderTransformOrigin- als auch die CenterX / CenterY-Werte anwenden, insbesondere, wenn Sie einen der Werte animieren.

Für Treffertests reagiert ein Objekt, auf das eine Transformation angewendet wird, weiterhin auf eingaben in einer erwarteten Weise, die mit seiner visuellen Darstellung im x-y-Raum konsistent ist. Wenn Sie beispielsweise ein TranslateTransform- genutzt haben, um ein Rechteck- 400 Pixel seitlich auf der Benutzeroberfläche zu verschieben, reagiert das Rechteck- auf PointerPressed--Ereignisse, wenn der Benutzer den Punkt anklickt, an dem das Rechteck- visuell angezeigt wird. Sie erhalten keine falschen Ereignisse, wenn der Benutzer den Bereich drückt, in dem das Rechteck war, bevor er übersetzt wurde. Für alle Z-Index-Überlegungen, die Treffertests betreffen, macht das Anwenden einer Transformation keinen Unterschied; Der Z-Index, der steuert, welches Element Eingabeereignisse für einen Punkt im x-y-Raum verarbeitet, wird weiterhin mithilfe der untergeordneten Reihenfolge ausgewertet, wie in einem Container deklariert. Diese Reihenfolge entspricht in der Regel der Reihenfolge, in der Sie die Elemente in XAML deklarieren, obwohl Sie für untergeordnete Elemente eines Canvas--Objekts die Reihenfolge anpassen können, indem Sie die Canvas.ZIndex angefügte Eigenschaft auf untergeordnete Elemente anwenden.

Andere Transformationseigenschaften

  • Brush.Transform, Brush.RelativeTransform: Diese beeinflussen, wie ein Brush den Koordinatenbereich innerhalb des Bereichs verwendet, in dem die Brush angewendet wird, um visuelle Eigenschaften wie Vordergrund und Hintergründe festzulegen. Diese Transformationen sind für die am häufigsten verwendeten Pinsel nicht relevant (die in der Regel Volltonfarben mit SolidColorBrushfestlegen), können aber gelegentlich nützlich sein, wenn Bereiche mit einem ImageBrush oder LinearGradientBrushgestaltet werden.
  • Geometry.Transform: Sie können diese Eigenschaft verwenden, um eine Transformation auf eine Geometrie anzuwenden, bevor Sie diese Geometrie für einen Path.Data- Eigenschaftswert verwenden.

Animieren einer Transformation

Transform Objekte können animiert werden. Um eine Transformzu animieren, wenden Sie eine Animation eines kompatiblen Typs auf die Eigenschaft an, die Sie animieren möchten. Dies bedeutet in der Regel, dass Sie DoubleAnimation oder DoubleAnimationUsingKeyFrames Objekte verwenden, um die Animation zu definieren, da alle Transformationseigenschaften vom Typ Doublesind. Animationen, die sich auf Transformationen auswirken, die für einen UIElement.RenderTransform Wert verwendet werden, werden nicht als abhängige Animationen betrachtet, selbst wenn sie eine Dauer ungleich null haben. Weitere Informationen zu abhängigen Animationen finden Sie unter Storyboard-gesteuerte Animationen.

Wenn Sie Eigenschaften animieren, um eine Wirkung zu erzeugen, die ein ähnliches visuelles Erscheinungsbild wie eine Transformation hat—z. B. das Animieren der Width und Height eines FrameworkElement anstatt eine TranslateTransformanzuwenden—werden solche Animationen fast immer als abhängige Animationen eingestuft. Sie müssen die Animationen aktivieren, und es können erhebliche Leistungsprobleme mit der Animation auftreten, insbesondere, wenn Sie versuchen, die Benutzerinteraktion zu unterstützen, während dieses Objekt animiert wird. Aus diesem Grund empfiehlt es sich, eine Transformation zu verwenden und zu animieren, anstatt eine andere Eigenschaft zu animieren, bei der die Animation als abhängige Animation behandelt wird.

Um die Transformation als Ziel festzulegen, muss eine vorhandene Transform- als Wert für RenderTransform-vorhanden sein. In der Regel fügen Sie ein Element für den entsprechenden Transformationstyp in den anfänglichen XAML-Code ein, manchmal ohne Eigenschaften, die für diese Transformation festgelegt sind.

In der Regel verwenden Sie eine indirekte Zieltechnik, um Animationen auf die Eigenschaften einer Transformation anzuwenden. Weitere Informationen zur Syntax der indirekten Zielbestimmung finden Sie unter Storyboardanimationen und Property-Path-Syntax.

Standardstile für Steuerelemente definieren manchmal Animationen von Transformationen als Teil ihres visuellen Zustandsverhaltens. Beispielsweise verwenden die visuellen Zustände für ProgressRing animierte RotateTransform Werte, um die Punkte im Ring zu "rotieren".

Hier ist ein einfaches Beispiel für das Animieren einer Transformation. In diesem Fall wird der Winkel eines RotateTransform- animiert, um ein Rechteck um seinen visuellen Mittelpunkt zu rotieren. In diesem Beispiel wird die RotateTransform- benannt, sodass keine indirekte Animationsadressierung erforderlich ist. Alternativ können Sie die Transformation jedoch unbenannt lassen, das Element benennen, auf das die Transformation angewendet wird, und indirekte Zielbestimmung wie (UIElement.RenderTransform).(RotateTransform.Angle)verwenden.

<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();
}

Berücksichtigung von Referenzkoordinatensystemen zur Laufzeit

UIElement- verfügt über eine Methode namens TransformToVisual, die eine Transform- generieren kann, die die Koordinatenreferenzrahmen für zwei UI-Elemente in Beziehung setzt. Damit können Sie ein Element mit dem Standard-Koordinatenrahmen der App vergleichen, wenn Sie das Root-Visual als ersten Parameter übergeben. Dies kann nützlich sein, wenn Sie ein Eingabeereignis aus einem anderen Element erfasst haben oder wenn Sie versuchen, das Layoutverhalten vorherzusagen, ohne tatsächlich einen Layoutdurchlauf anzufordern.

Hinweis

(UWP) Ereignisdaten, die von Zeigerereignissen abgerufen werden, bieten Zugriff auf die Methode GetCurrentPoint, bei der Sie einen relativeTo-Parameter angeben können, um den Koordinatenrahmen auf ein bestimmtes Element zu ändern, anstatt auf den App-Standard. Dieser Ansatz wendet einfach intern eine Übersetzungstransformation an und transformiert die x-y-Koordinatendaten für Sie, wenn sie das zurückgegebene PointerPoint--Objekt erstellt.

Das mathematische Beschreiben einer Transformation

Eine Transformation kann in Bezug auf eine Transformationsmatrix beschrieben werden. Eine 3×3-Matrix wird verwendet, um die Transformationen in einer zweidimensionalen x-y-Ebene zu beschreiben. Affine Transformationsmatrizen können multipliziert werden, um eine beliebige Anzahl linearer Transformationen zu bilden, z. B. Drehung und Verzerrung (Scherung), gefolgt von Übersetzung. Die letzte Spalte einer affinen Transformationsmatrix ist gleich (0, 0, 1), daher müssen Sie nur die Elemente der ersten beiden Spalten in der mathematischen Beschreibung angeben.

Die mathematische Beschreibung einer Transformation kann für Sie nützlich sein, wenn Sie über einen mathematischen Hintergrund oder eine Vertrautheit mit Grafikprogrammiertechniken verfügen, die auch Matrizen verwenden, um Transformationen des Koordinatenraums zu beschreiben. Es gibt eine von Transformabgeleitete Klasse, die es Ihnen ermöglicht, eine Transformation direkt in Bezug auf ihre 3×3-Matrix auszudrücken: MatrixTransform-. MatrixTransform hat eine Matrix-Eigenschaft, die eine Struktur mit sechs Eigenschaften enthält: M11, M12, M21, M22, OffsetX und OffsetY. Jede Matrix-Eigenschaft verwendet einen Double-Wert und entspricht den sechs relevanten Werten (Spalten 1 und 2) einer affinen Transformationsmatrix.

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

Jede Transformation, die Sie mit einem TranslateTransform-, ScaleTransform-, RotateTransform-oder SkewTransform--Objekt beschreiben könnten, kann auch durch ein MatrixTransform- mit einem Matrix--Wert beschrieben werden. In der Regel verwenden Sie jedoch nur TranslateTransform und die anderen Transformationen, da sich die Eigenschaften dieser Klassen einfacher konzeptualisieren lassen als das Festlegen der Vektorkomponenten in einer Matrix. Es ist auch einfacher, die diskreten Eigenschaften von Transformationen zu animieren; eine Matrix ist tatsächlich eine Struktur und nicht ein DependencyObject, daher können animierte einzelne Werte nicht unterstützt werden.

Einige XAML-Designtools, mit denen Sie Transformationen anwenden können, serialisieren die Ergebnisse als MatrixTransform-. In diesem Fall kann es am besten sein, dasselbe Designtool erneut zu verwenden, um den Transformationseffekt zu ändern und den XAML-Code erneut zu serialisieren, anstatt die Matrixwerte selbst direkt im XAML-Code zu bearbeiten.

3D-Transformationen

In Windows 10 wurde mit XAML eine neue Eigenschaft " UIElement.Transform3D" eingeführt, die zum Erstellen von 3D-Effekten mit der Benutzeroberfläche verwendet werden kann. Verwenden Sie dazu PerspectiveTransform3D-, um Ihrer Szene eine freigegebene 3D-Perspektive oder "Kamera" hinzuzufügen, und anschließend CompositeTransform3D-, um ein Element im 3D-Raum zu transformieren, so wie Sie CompositeTransform-verwenden würden. Weitere Informationen zur Implementierung von 3D-Transformationen finden Sie unter UIElement.Transform3D.

Für einfachere 3D-Effekte, die nur auf ein einzelnes Objekt angewendet werden, kann man die UIElement.Projection-Eigenschaft verwenden. Die Verwendung eines PlaneProjection- als Werts für diese Eigenschaft entspricht dem Anwenden einer festen perspektivischen Transformation und einer oder mehrerer 3D-Transformationen auf das Element. Dieser Transformationstyp wird ausführlicher in den 3D-Perspektiveneffekten für XAML-UIbeschrieben.