Freigeben über


Formen und grundlegende Zeichnung in WPF (Übersicht)

In diesem Thema finden Sie eine Übersicht über das Zeichnen mit Shape Objekten. Ein Shape ist eine Art von UIElement, mit der Sie eine Form auf den Bildschirm zeichnen können. Da es sich um UI-Elemente handelt, können Shape Objekte innerhalb von Panel Elementen und den meisten Steuerelementen verwendet werden.

Windows Presentation Foundation (WPF) bietet mehrere Ebenen des Zugriffs auf Grafik- und Renderingdienste. Auf der oberen Ebene Shape sind Objekte einfach zu verwenden und bieten viele nützliche Features, z. B. Layout und Teilnahme am Windows Presentation Foundation (WPF)-Ereignissystem.

Shape-bezogene Typen befinden sich im Windows.Shapes Namespace. Geometriebezogene Typen befinden sich im System.Windows.Media Namespace.

Shape-Objekte

WPF stellt eine Reihe von einsatzbereiten Shape Objekten bereit. Alle Shape-Objekte erben von der Shape-Klasse. Verfügbare Shape-Objekte sind Ellipse, Line, Path, Polygon, Polylineund Rectangle. Shape Objekte teilen die folgenden allgemeinen Eigenschaften.

  • Stroke: Beschreibt, wie die Kontur der Form gezeichnet wird.

  • StrokeThickness: Beschreibt die Dicke der Kontur der Form.

  • Fill: Beschreibt, wie das Innere der Form gezeichnet wird.

  • Dateneigenschaften zum Angeben von Koordinaten und Scheitelpunkten, gemessen in geräteunabhängigen Pixeln.

Da sie von UIElement abgeleitet werden, können Shape-Objekte innerhalb von Panels und den meisten Steuerelementen verwendet werden. Das Canvas Panel ist eine besonders gute Wahl zum Erstellen komplexer Zeichnungen, da es die absolute Positionierung seiner untergeordneten Objekte unterstützt.

Mit der Line Klasse können Sie eine Linie zwischen zwei Punkten zeichnen. Das folgende Beispiel zeigt verschiedene Möglichkeiten zum Angeben von Linienkoordinaten und Stricheigenschaften.

<Canvas Height="300" Width="300">

  <!-- Draws a diagonal line from (10,10) to (50,50). -->
  <Line
    X1="10" Y1="10"
    X2="50" Y2="50"
    Stroke="Black"
    StrokeThickness="4" />

  <!-- Draws a diagonal line from (10,10) to (50,50)
       and moves it 100 pixels to the right. -->
  <Line
    X1="10" Y1="10"
    X2="50" Y2="50"
    StrokeThickness="4"
    Canvas.Left="100">
    <Line.Stroke>
      <RadialGradientBrush GradientOrigin="0.5,0.5" Center="0.5,0.5" RadiusX="0.5" RadiusY="0.5">
        <RadialGradientBrush.GradientStops>
          <GradientStop Color="Red" Offset="0" />
          <GradientStop Color="Blue" Offset="0.25" />
        </RadialGradientBrush.GradientStops>
      </RadialGradientBrush>
    </Line.Stroke>
  </Line>

  <!-- Draws a horizontal line from (10,60) to (150,60). -->
  <Line
     X1="10" Y1="60"
     X2="150" Y2="60"
     Stroke="Black"
     StrokeThickness="4"/>

</Canvas>

// Add a Line Element
myLine = gcnew Line();
myLine->Stroke = Brushes::LightSteelBlue;
myLine->X1 = 1;
myLine->X2 = 50;
myLine->Y1 = 1;
myLine->Y2 = 50;
myLine->HorizontalAlignment = HorizontalAlignment::Left;
myLine->VerticalAlignment = VerticalAlignment::Center;
myLine->StrokeThickness = 2;
myGrid->Children->Add(myLine);

// Add a Line Element
myLine = new Line();
myLine.Stroke = System.Windows.Media.Brushes.LightSteelBlue;
myLine.X1 = 1;
myLine.X2 = 50;
myLine.Y1 = 1;
myLine.Y2 = 50;
myLine.HorizontalAlignment = HorizontalAlignment.Left;
myLine.VerticalAlignment = VerticalAlignment.Center;
myLine.StrokeThickness = 2;
myGrid.Children.Add(myLine);

' Add a Line Element
Dim myLine As New Line()
myLine.Stroke = Brushes.LightSteelBlue
myLine.X1 = 1
myLine.X2 = 50
myLine.Y1 = 1
myLine.Y2 = 50
myLine.HorizontalAlignment = HorizontalAlignment.Left
myLine.VerticalAlignment = VerticalAlignment.Center
myLine.StrokeThickness = 2
myGrid.Children.Add(myLine)

Die folgende Abbildung zeigt das gerenderte Line.

Liniendarstellung

Obwohl die Line Klasse eine Fill Eigenschaft bereitstellt, hat die Einstellung keine Auswirkung, da kein Line Bereich vorhanden ist.

Ein weiteres gängiges Shape ist die Ellipse. Erstellen Sie ein Ellipse, indem Sie die Width- und Height-Eigenschaften des Shapes definieren. Wenn Sie einen Kreis zeichnen möchten, geben Sie einen Ellipse Wert an, dessen Width Werte gleich Height sind.

<Ellipse
Fill="Yellow"
Height="100"
Width="200"
StrokeThickness="2"
Stroke="Black"/>

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace SDKSample
{
    public partial class SetBackgroundColorOfShapeExample : Page
    {
        public SetBackgroundColorOfShapeExample()
        {
            // Create a StackPanel to contain the shape.
            StackPanel myStackPanel = new StackPanel();

            // Create a red Ellipse.
            Ellipse myEllipse = new Ellipse();

            // Create a SolidColorBrush with a red color to fill the
            // Ellipse with.
            SolidColorBrush mySolidColorBrush = new SolidColorBrush();

            // Describes the brush's color using RGB values.
            // Each value has a range of 0-255.
            mySolidColorBrush.Color = Color.FromArgb(255, 255, 255, 0);
            myEllipse.Fill = mySolidColorBrush;
            myEllipse.StrokeThickness = 2;
            myEllipse.Stroke = Brushes.Black;

            // Set the width and height of the Ellipse.
            myEllipse.Width = 200;
            myEllipse.Height = 100;

            // Add the Ellipse to the StackPanel.
            myStackPanel.Children.Add(myEllipse);

            this.Content = myStackPanel;
        }
    }
}

Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports System.Windows.Shapes

Namespace SDKSample
    Partial Public Class SetBackgroundColorOfShapeExample
        Inherits Page
        Public Sub New()
            ' Create a StackPanel to contain the shape.
            Dim myStackPanel As New StackPanel()

            ' Create a red Ellipse.
            Dim myEllipse As New Ellipse()

            ' Create a SolidColorBrush with a red color to fill the 
            ' Ellipse with.
            Dim mySolidColorBrush As New SolidColorBrush()

            ' Describes the brush's color using RGB values. 
            ' Each value has a range of 0-255.
            mySolidColorBrush.Color = Color.FromArgb(255, 255, 255, 0)
            myEllipse.Fill = mySolidColorBrush
            myEllipse.StrokeThickness = 2
            myEllipse.Stroke = Brushes.Black

            ' Set the width and height of the Ellipse.
            myEllipse.Width = 200
            myEllipse.Height = 100

            ' Add the Ellipse to the StackPanel.
            myStackPanel.Children.Add(myEllipse)

            Me.Content = myStackPanel
        End Sub

    End Class
End Namespace

Die folgende Abbildung zeigt ein Beispiel für ein gerendertes Ellipse.

Ellipse-Abbildung

Verwenden von Pfaden und Geometrien

Mit der Path Klasse können Sie Kurven und komplexe Formen zeichnen. Diese Kurven und Formen werden mithilfe von Geometry Objekten beschrieben. Um ein PathObjekt zu verwenden, erstellen Sie eine Geometry und verwenden sie, um die Eigenschaft des PathData Objekts festzulegen.

Es gibt eine Vielzahl von Objekten, aus denen Geometry Sie wählen können. Die Klassen LineGeometry, RectangleGeometry und EllipseGeometry beschreiben relativ einfache Formen. Um komplexere Formen zu erstellen oder Kurven zu erstellen, verwenden Sie eine PathGeometry.

PathGeometry und PathSegments

PathGeometry Objekte bestehen aus einem oder PathFigure mehreren Objekten; jede PathFigure stellt eine andere "Figur" oder Form dar. Jeder PathFigure besteht aus einem oder PathSegment mehreren Objekten, die jeweils einen verbundenen Teil der Figur oder Form darstellen. Segmenttypen umfassen Folgendes: LineSegment, , BezierSegmentund ArcSegment.

Im folgenden Beispiel wird eine Path zum Zeichnen einer quadratischen Bézierkurve verwendet.

<Path Stroke="Black" StrokeThickness="1">
  <Path.Data>
    <PathGeometry>
      <PathGeometry.Figures>
        <PathFigureCollection>
          <PathFigure StartPoint="10,100">
            <PathFigure.Segments>
              <PathSegmentCollection>
                <QuadraticBezierSegment Point1="200,200" Point2="300,100" />
              </PathSegmentCollection>
            </PathFigure.Segments>
          </PathFigure>
        </PathFigureCollection>
      </PathGeometry.Figures>
    </PathGeometry>
  </Path.Data>
</Path>

Die folgende Abbildung zeigt die gerenderte Form.

Pfadabbildung

Weitere Informationen zu PathGeometry und den anderen Geometry Klassen finden Sie in der Geometry Overview.

Gekürzte XAML-Syntax

In Extensible Application Markup Language (XAML) können Sie auch eine spezielle abgekürzte Syntax verwenden, um eine Path. Im folgenden Beispiel wird abgekürzte Syntax verwendet, um eine komplexe Form zu zeichnen.

      <Path Stroke="DarkGoldenRod" StrokeThickness="3"
Data="M 100,200 C 100,25 400,350 400,175 H 280" />

Die folgende Abbildung zeigt ein gerendertes Path.

Eine zweite Pfad-Illustration.

Die Data-Attributzeichenfolge beginnt mit dem Befehl "moveto", der durch M angegeben wird, wodurch ein Startpunkt für den Pfad im Koordinatensystem des Canvas festgelegt wird. Path Datenparameter sind groß-/kleinschreibungssensitiv. Die Großbuchstaben M gibt eine absolute Position für den neuen aktuellen Punkt an. Ein Kleinbuchstaben m würde relative Koordinaten angeben. Das erste Segment ist eine kubische Bézierkurve beginnend bei (100.200) und endet mit (400.175), die mit den beiden Kontrollpunkten (100.25) und (400.350) gezeichnet wird. Dieses Segment wird durch den Befehl C in der Data Attributzeichenfolge angegeben. Auch hier zeigt ein großes C einen absoluten Pfad an; ein kleines c würde einen relativen Pfad anzeigen.

Das zweite Segment beginnt mit einem absoluten horizontalen "lineto"-Befehl H, der eine Linie angibt, die vom Endpunkt des vorhergehenden Unterpfads (400.175) zu einem neuen Endpunkt (280.175) gezeichnet wird. Da es sich um einen horizontalen "lineto"-Befehl handelt, ist der angegebene Wert eine X-Koordinate.

Die vollständige Pfadsyntax finden Sie in der Data Referenz und siehe Erstellen einer Form mit PathGeometry.

Malen von Formen

Brush Objekte werden verwendet, um die Stroke und Fill einer Form zu malen. Im folgenden Beispiel werden der Strich und die Füllung eines Ellipse angegeben. Beachten Sie, dass gültige Eingaben für Pinseleigenschaften entweder ein Schlüsselwort oder eine Hexadezimalfarbe sein können. Weitere Informationen zu verfügbaren Farbstichwörtern finden Sie unter Eigenschaften der Colors Klasse im System.Windows.Media Namespace.

<Canvas Background="LightGray">
   <Ellipse
      Canvas.Top="50"
      Canvas.Left="50"
      Fill="#FFFFFF00"
      Height="75"
      Width="75"
      StrokeThickness="5"
      Stroke="#FF0000FF"/>
</Canvas>

Die folgende Abbildung zeigt das gerenderte Ellipse.

Eine Ellipse

Alternativ können Sie die Eigenschaftselementsyntax verwenden, um explizit ein SolidColorBrush Objekt zu erstellen, um die Form mit einer Volltonfarbe zu zeichnen.

<!-- This polygon shape uses pre-defined color values for its Stroke and
     Fill properties.
     The SolidColorBrush's Opacity property affects the fill color in
     this case by making it slightly transparent (opacity of 0.4) so
     that it blends with any underlying color. -->

<Polygon
    Points="300,200 400,125 400,275 300,200"
    Stroke="Purple"
    StrokeThickness="2">
    <Polygon.Fill>
       <SolidColorBrush Color="Blue" Opacity="0.4"/>
    </Polygon.Fill>
</Polygon>

Die folgende Abbildung zeigt die gerenderte Form.

SolidColorBrush-Abbildung

Sie können auch die Kontur oder die Füllung eines Shapes mit Farbverläufen, Bildern, Mustern und mehr gestalten. Weitere Informationen finden Sie unter Übersicht über das Malen mit Vollfarben und Farbverläufen.

Dehnbare Formen

Die LineKlassen , Path, Polygon, Polylineund Rectangle die Klassen verfügen alle über eine Stretch Eigenschaft. Diese Eigenschaft bestimmt, wie der Inhalt eines Shape Objekts (die zu zeichnende Form) gestreckt wird, um den Layoutbereich des Shape Objekts auszufüllen. Shape Der Layoutbereich eines Objekts ist der vom Layoutsystem zugewiesene PlatzShape, aufgrund einer expliziten Width- und Height-Einstellung oder aufgrund seiner HorizontalAlignment- und VerticalAlignment-Einstellungen. Weitere Informationen zum Layout in Windows Presentation Foundation finden Sie in der Layoutübersicht .

Die Stretch-Eigenschaft akzeptiert einen der folgenden Werte:

  • None: Der Inhalt des Shape Objekts wird nicht gestreckt.

  • Fill: Der Inhalt des Shape-Objekts wird gestreckt, um seinen Layoutbereich auszufüllen. Das Seitenverhältnis wird nicht beibehalten.

  • Uniform: Der Shape Inhalt des Objekts wird so weit wie möglich gestreckt, um den Layoutbereich zu füllen und gleichzeitig das ursprüngliche Seitenverhältnis beizubehalten.

  • UniformToFill: Die Inhalte des Shape-Objekts werden gestreckt, um den Layoutbereich vollständig auszufüllen und gleichzeitig das ursprüngliche Seitenverhältnis beizubehalten.

Beachten Sie, dass, wenn der Inhalt eines Shape Objekts gestreckt wird, die Kontur des Shape Objekts nach dem Dehnen gezeichnet wird.

Im folgenden Beispiel wird ein sehr kleines Dreieck von (0,0) nach (0,1) und dann nach (1,1) mit einem Polygon gezeichnet. Die Polygon Objekte Width und Height werden auf 100 festgelegt, und die Stretch-Eigenschaft wird auf Fill festgelegt. Daher werden die Inhalte des Objekts Polygon (das Dreieck) gestreckt, um den größeren Raum auszufüllen.

<Polygon
  Points="0,0 0,1 1,1"
  Fill="Blue"
  Width="100"
  Height="100"
  Stretch="Fill"
  Stroke="Black"
  StrokeThickness="2" />
PointCollection myPointCollection = new PointCollection();
myPointCollection.Add(new Point(0,0));
myPointCollection.Add(new Point(0,1));
myPointCollection.Add(new Point(1,1));

Polygon myPolygon = new Polygon();
myPolygon.Points = myPointCollection;
myPolygon.Fill = Brushes.Blue;
myPolygon.Width = 100;
myPolygon.Height = 100;
myPolygon.Stretch = Stretch.Fill;
myPolygon.Stroke = Brushes.Black;
myPolygon.StrokeThickness = 2;

Verwandlung von Formen

Die Transform Klasse stellt die Mittel zum Transformieren von Formen in einer zweidimensionalen Ebene bereit. Zu den verschiedenen Transformationstypen gehören Drehung (RotateTransform), Skalierung (ScaleTransform), Schiefe (SkewTransform) und Übersetzung (TranslateTransform).

Eine häufige Transformation, die auf ein Shape angewendet werden soll, ist eine Drehung. Um eine Form zu drehen, erstellen Sie eine RotateTransform und geben Sie Angle an. Ein Wert von 45 dreht das Element um 45 Grad im Uhrzeigersinn. Ein Angle Winkel von 90 dreht das Element um 90 Grad im Uhrzeigersinn usw. Legen Sie die Eigenschaften CenterX und CenterY fest, wenn Sie den Punkt steuern möchten, um den das Element gedreht wird. Diese Eigenschaftswerte werden im Koordinatenbereich des transformierten Elements ausgedrückt. CenterX und CenterY haben Standardwerte von Null. Wenden Sie schließlich das RotateTransform Element an. Wenn sich die Transformation nicht auf das Layout auswirken soll, legen Sie die Eigenschaft des RenderTransform Shapes fest.

Im folgenden Beispiel wird eine RotateTransform Form um 45 Grad um die obere linke Ecke der Form gedreht (0,0).

<!-- Rotates the Polyline 45 degrees about the point (0,0). -->
<Polyline Points="25,25 0,50 25,75 50,50 25,25 25,0" 
  Stroke="Blue" StrokeThickness="10"
  Canvas.Left="75" Canvas.Top="50">
  <Polyline.RenderTransform>
    <RotateTransform CenterX="0" CenterY="0" Angle="45" />
  </Polyline.RenderTransform>
</Polyline>

Im nächsten Beispiel wird eine andere Form um 45 Grad gedreht, aber dieses Mal wird es um den Punkt gedreht (25.50).

<!-- Rotates the Polyline 45 degrees about its center. -->
<Polyline 
  Points="25,25 0,50 25,75 50,50 25,25 25,0" 
  Stroke="Blue" StrokeThickness="10"
  Canvas.Left="75" Canvas.Top="50"
  RenderTransformOrigin="0.5,0.5">
  <Polyline.RenderTransform>
    <RotateTransform Angle="45" />
  </Polyline.RenderTransform>
</Polyline>

Die folgende Abbildung zeigt die Ergebnisse der Anwendung der beiden Transformationen.

Drehungen um 45 Grad mit unterschiedlichen Mittelpunkten

In den vorherigen Beispielen wurde eine einzelne Transformation auf jedes Shape-Objekt angewendet. Um mehrere Transformationen auf ein Shape (oder ein beliebiges anderes UI-Element) anzuwenden, verwenden Sie eine TransformGroup.

Siehe auch