Share via


Ü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 Koordinatenbereich zu einem anderen Koordinatenbereich 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: Übersetzung, Drehung, Skalierung und Schiefe (oder Schere). 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:

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

Sie können Transformationen kombinieren, und es gibt zwei Windows-Runtime Klassen, die folgendes unterstützen: CompositeTransform und TransformGroup. In einer CompositeTransform werden Transformationen in dieser Reihenfolge angewendet: Skalieren, Schiefe, Drehen, Übersetzen. Verwenden Sie TransformGroup anstelle von CompositeTransform , wenn die Transformationen in einer anderen Reihenfolge angewendet werden sollen. Weitere Informationen finden Sie unter CompositeTransform.

Transformationen und Layout

Im XAML-Layout werden Transformationen angewendet, nachdem der Layoutdurchlauf abgeschlossen ist, sodass verfügbare Raumberechnungen und andere Layoutentscheidungen getroffen wurden, bevor die Transformationen angewendet werden. Da das Layout zuerst eintritt, erhalten Sie manchmal unerwartete Ergebnisse, wenn Sie Elemente transformieren, die sich in einer Rasterzelle oder einem ähnlichen Layoutcontainer befinden, der Platz während des Layouts zuweist. Das transformierte Element wird möglicherweise abgeschnitten oder verdeckt angezeigt, da es versucht, in einen Bereich zu zeichnen, der die Dimensionen nach der Transformation beim Teilen des Raums innerhalb des übergeordneten Containers nicht berechnet hat. Möglicherweise müssen Sie mit den Transformationsergebnissen experimentieren und einige Einstellungen anpassen. Anstatt z. B. auf adaptives Layout und Sterngröße zu vertrauen, müssen Sie möglicherweise die Center-Eigenschaften ändern oder feste Pixelmaße für den Layoutbereich deklarieren, um sicherzustellen, dass die übergeordneten Klammern ausreichend Platz haben.

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 hat diese Eigenschaft auch nicht verwendet.)

Als Alternative bietet das Windows-Community Toolkit das LayoutTransformControl-Element, das Matrixtransformationen auf jedes FrameworkElement Ihrer Anwendung anwendet.

Anwenden einer Transformation auf ein UI-Element

Wenn Sie eine Transformation auf ein Objekt anwenden, legen Sie in der Regel die Eigenschaft UIElement.RenderTransform fest. Das Festlegen dieser Eigenschaft ändert das Objektpixel nicht buchstäblich um Pixel. Was die Eigenschaft wirklich tut, wird die Transformation innerhalb des lokalen Koordinatenraums angewendet, in dem das Objekt vorhanden ist. Anschließend rendert die Renderlogik und der Vorgang (post-layout) die kombinierten Koordinatenräume, sodass es so aussieht, als ob das Objekt die Darstellung geändert hat und auch die Layoutposition (wenn 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 jeweils Eigenschaften auf, die CenterX- und CenterY-Werte festlegen.

Wenn Sie Transformationen mit UIElement.RenderTransform verwenden, denken Sie daran, dass es eine andere Eigenschaft für UIElement gibt, die sich auf das Verhalten der Transformation auswirkt: 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, wenn Sie sowohl RenderTransformOrigin- als auch CenterX / CenterY-Werte anwenden, ziemlich verwirrend sein können, 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 eine TranslateTransform verwendet haben, um ein Rechteck mit 400 Pixeln später auf der Benutzeroberfläche zu verschieben, reagiert dieses Rechteck auf PointerPressed-Ereignisse, wenn der Benutzer den Punkt drückt, an dem das Rechteck visuell angezeigt wird. Sie erhalten keine falschen Ereignisse, wenn der Benutzer den Bereich drückt, in dem sich das Rechteck befand, bevor es ü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 angefügte Canvas.ZIndex-Eigenschaft auf untergeordnete Elemente anwenden.

Andere Transformationseigenschaften

  • Brush.Transform, Brush.RelativeTransform: Diese beeinflussen, wie ein Pinsel Koordinatenbereich innerhalb des Bereichs verwendet, auf den der Pinsel angewendet wird, um visuelle Eigenschaften wie Vordergrund und Hintergründe festzulegen. Diese Transformationen sind für die am häufigsten verwendeten Pinsel (die in der Regel Volltonfarben mit SolidColorBrush festlegen) nicht relevant, können aber gelegentlich hilfreich sein, wenn Bereiche mit einem ImageBrush oder LinearGradientBrush gefärbt 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 Transformation zu 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 Double sind. Animationen, die sich auf eine Transformation auswirken, die für einen UIElement.RenderTransform-Wert verwendet wird, werden nicht als abhängige Animationen betrachtet, auch wenn sie eine Nichtzero-Dauer aufweisen. Weitere Informationen zu abhängigen Animationen finden Sie unter Storyboardanimationen.

Wenn Sie Eigenschaften animieren, um einen Effekt zu erzeugen, der einer Transformation in Bezug auf die visuelle Darstellung des Netzs ähnelt, z. B. die Animationen für breite und höhe eines FrameworkElements, anstatt eine TranslateTransform anzuwenden, werden diese Animationen fast immer als abhängige Animationen behandelt. 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, in der die Animation als abhängige Animation behandelt wird.

Um die Transformation als Ziel festzulegen, muss eine vorhandene Transformation 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 "drehen".

Hier ist ein einfaches Beispiel für das Animieren einer Transformation. In diesem Fall wird der Winkel eines RotateTransform-Shapes animiert, um ein Rechteck um seine visuelle Mitte zu drehen. 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 verwenden, z (UIElement.RenderTransform).(RotateTransform.Angle). B. .

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

Angeben von Referenz-Koordinatennetzen zur Laufzeit

UIElement verfügt über eine Methode mit der Bezeichnung TransformToVisual, die ein Transform-Element generieren kann, das die Referenz-Koordinatennetze für zwei UI-Elemente abgleicht. Damit können Sie ein Element mit dem Standardkoordinatenframe der App vergleichen, wenn Sie das Stammvisual 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.

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

Mathematische Beschreibung 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 Schiefe (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 transform-abgeleitete Klasse, mit der Sie eine Transformation direkt in Bezug auf ihre 3×3-Matrix ausdrücken können: MatrixTransform. MatrixTransform verfügt über 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önnen, kann auch durch ein MatrixTransform-Objekt mit einem Matrixwert beschrieben werden. In der Regel verwenden Sie jedoch einfach TranslateTransform und die anderen, da die Eigenschaften dieser Transformationsklassen einfacher konzeptualisiert werden können, als die Vektorkomponenten in einer Matrix festzulegen. Es ist auch einfacher, die diskreten Eigenschaften von Transformationen zu animieren; eine Matrix ist tatsächlich eine Struktur und kein DependencyObject, sodass animierte einzelne Werte nicht unterstützt werden können.

Einige XAML-Designtools, mit denen Sie Transformationsvorgänge 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 verwenden Sie dann CompositeTransform3D, um ein Element im 3D-Raum zu transformieren, wie Sie CompositeTransform verwenden würden. Eine Erläuterung zur Implementierung von 3D-Transformationen finden Sie unter UIElement.Transform3D.

Für einfachere 3D-Effekte, die nur für ein einzelnes Objekt gelten, kann die UIElement.Projection-Eigenschaft verwendet werden. Die Verwendung einer PlaneProjection als Wert für diese Eigenschaft entspricht dem Anwenden einer festen Perspektivtransformation und mindestens einer 3D-Transformation auf das Element. Dieser Transformationstyp wird ausführlicher in 3D-Perspektiveneffekten für die XAML-Benutzeroberfläche beschrieben.