Mehrfach-Transformation von UI-Elementen in WPF
So nach einer zweichwöchigen Pause melde ich mich nun wieder zum Thema WPF. Da ich zur Zeit sehr viel mit dieser Thematik zu tun habe, werde ich wohl noch das ein oder andere Mal Beiträge zu 2D-Grafiken in WPF schreiben.
Hier nun ein kurzes Beispiel in dem gezeigt wird das man ein UI-Element wie eine Geometrie oder auch z.B. ein Bild mit mehreren Transforms des gleichen Typs transformieren kann. Das bedeutet ich kann z.B. eine Geometrie nicht nur einmal gleichzeitig Rotieren sondern mehrfach, einmal um den eigenen Nullpunkt und einmal um einen versetzten Nullpunkt. Der Vorteil dabei ist das ich nicht wild umher rechnen muss sondern ganz bequem meine Transformationen auf einmal erledigen kann.
Als Beispiel soll eine einfache Geometrie (das Haus vom Nikolaus mit Schrägdach) dienen, auf die drei Transformationen gleichzeitig angewendet werden. Dazu dient folgender Beispielcode:
//Erzeugen des Path, der PathGeometry und der PathFigure //für die Haus-Figur Path tmpPath = new Path(); PathGeometry tmpPathGeometry = new PathGeometry(); PathFigure tmpPathFigure = new PathFigure(); //Hilfskreis der den Nullpunkt anzeigt Ellipse tmpEllipse = new Ellipse(); tmpEllipse.Margin = new Thickness(2); tmpEllipse.Width = 5; tmpEllipse.Height = 5; tmpEllipse.Stroke = new SolidColorBrush(Color.FromArgb(255,255,0,0)); tmpEllipse.StrokeThickness = 4; canvas1.Children.Add(tmpEllipse); //Erstellen der Haus-Figur tmpPath.Stroke = new SolidColorBrush(Color.FromArgb(255,0,0,255)); tmpPath.StrokeThickness = 4; tmpPath.StrokeLineJoin = PenLineJoin.Round; tmpPathFigure.StartPoint = new Point(0, 0); tmpPathFigure.Segments.Add(new LineSegment(new Point(0, 100), true)); tmpPathFigure.Segments.Add(new LineSegment(new Point(0, 150), true)); tmpPathFigure.Segments.Add(new LineSegment(new Point(100, 100), true)); tmpPathFigure.Segments.Add(new LineSegment(new Point(100, 0), true)); tmpPathFigure.Segments.Add(new LineSegment(new Point(0, 100), true)); tmpPathFigure.Segments.Add(new LineSegment(new Point(100, 100), true)); tmpPathFigure.Segments.Add(new LineSegment(new Point(0, 0), true)); tmpPathFigure.Segments.Add(new LineSegment(new Point(100, 0), true)); tmpPathFigure.IsClosed = true; tmpPathGeometry.Figures.Add(tmpPathFigure); tmpPath.Data=tmpPathGeometry; canvas1.Children.Add(tmpPath);
Dieser Quelltext erstellt sowohl einen roten Punkt im Nullpunkt von WPF wie auch die Haus-Figur und fügt die Elemente einem Canvas hinzu. Das Folgende Bild zeigt die oben generierten Geometrien:
Zu beachten ist das in WPF der Nullpunkt links oben liegt, dadurch steht die Haus-Figur auf dem Kopf. Wie man sieht hat die Figur ein schräges Dach, dies dient hier nur zur besseren Erkennung der Winkellage.
Jetzt werden drei verschiedene Transformvarianten erstellt, ein ScaleTransform und zwei RotateTransform. Diese werden in einem GroupTransform zusammengefasst damit alle Transformationen auf einmal ausgeführt werden könne. Das besondere hierbei ist nun das beide Rotationen auf die Geometrie angewendet werden und nicht nur eine.
TransformGroup tmpTransformGroup = new TransformGroup(); ScaleTransform tmpScaleTransform = new ScaleTransform(); RotateTransform tmpRotateTransform = new RotateTransform(); RotateTransform tmpRotateTransform2 = new RotateTransform(); tmpTransformGroup.Children.Add(tmpRotateTransform); tmpTransformGroup.Children.Add(tmpRotateTransform2); tmpTransformGroup.Children.Add(tmpScaleTransform); tmpPathGeometry.Transform = tmpTransformGroup;
Als zweiter Schritt soll die Figur um die X-Achser gespiegelt werden damit Sie nicht mehr auf dem Kopf steht. Hierzu verwendet man ein ScaleTransforme und setzt den ScaleY Wert (da um die X-Achse gespiegelt werden soll) auf -1. Um die Geometrie nicht um den Nullpunkt zu spiegeln sondern um den Mittelpunkt, kann man die Eigenschaft CenterY auf die Hälfte der Figurhöhe, hier 75, setzten. Folgender Code ist hierfür nötig:
//Spiegelung um die X-Achse tmpScaleTransform.ScaleY = -1; tmpScaleTransform.CenterY = 75;
Dadurch entsteht folgende Grafik:
Man beachte das der Nullpunkt der Grafik nun nicht mehr im Nullpunkt des Canvas liegt, sondern in der Linken unteren Ecke der Haus-Figur.
Als nächstes soll eine Rotation um den Nullpunkt (also links unten) der Haus-Figur um -90° durchgeführt werden. Folgender Code ist dazu nötig:
//Rotation um den Nullpunkt der Haus-Figur tmpRotateTransform.Angle = -90;
Hieraus resultiert folgende Grafik:
Als letztes soll eine zweite Rotation ausgeführt werden, dieses mal aber um den Nullpunkt des Canvas (also den roten Punkt). Dazu muss der Nullpunkt der Rotation, der zur Zeit noch im Nullpunkt der Haus-Figur liegt auf den Nullpunkt des Canvas verschoben werden. Hierzu wird die CenterY Eigenschaft des RotateTransform bemüht. Folgender Code bringt uns zum Ziel:
//Rotation um den Nullpunkt des Canvas-Koordinatensystems tmpRotateTransform2.CenterY = 150; tmpRotateTransform2.Angle = 45;
Daraus entsteht folgende Grafik:
Man sieht das mit diesen wenigen Schritten auch eine Mehrfach-Rotation möglich ist. Es ist also durchaus sinnvoll seine Rotationen nicht umständlich in eine Rotation mit evt. noch anderen Transformationen umzurechnen, sondern diese Schritt für nacheinander auszuführen.
Juni 4th, 2008 at 19:03
Thalgo…
I found your site on technorati and read a few of your other posts. Keep up the good work. I just added your RSS feed to my Google News Reader. Looking forward to reading more from you….