Condividi tramite


Cenni preliminari sugli oggetti Shape e sulle funzionalità di disegno di base di WPF

In questo argomento vengono forniti cenni preliminari su come disegnare con oggetti Shape. Shape è un tipo di UIElement che consente di disegnare una forma sullo schermo. Poiché si tratta di elementi dell'interfaccia utente, è possibile utilizzare gli oggetti Shape all'interno degli elementi Panel e della maggior parte dei controlli.

In Windows Presentation Foundation (WPF) vengono offerti molti livelli di accesso alla grafica e ai servizi di rendering. Al livello superiore, gli oggetti Shape sono facili da utilizzare e forniscono varie funzionalità utili, ad esempio il layout e la partecipazione nel sistema di eventi Windows Presentation Foundation (WPF).

Nel presente argomento sono contenute le seguenti sezioni.

  • Oggetti Shape
  • Utilizzo di percorsi e geometrie
  • Disegno di oggetti Shape
  • Oggetti Shape allungabili
  • Trasformazione degli oggetti Shape
  • Argomenti correlati

Oggetti Shape

WPF offre vari oggetti Shape pronti all'uso. Tutti gli oggetti Shape ereditano dalla classe Shape. Gli oggetti Shape disponibili comprendono Ellipse, Line, Path, Polygon, Polyline e Rectangle. Gli oggetti Shape condividono le seguenti proprietà comuni.

  • Stroke: indica come viene disegnata la struttura della forma.

  • StrokeThickness: indica lo spessore della struttura della forma.

  • Fill: indica come viene disegnata la parte interna della forma.

  • Proprietà dei dati per specificare coordinate e vertici, misurati in pixel indipendenti dal dispositivo.

Dal momento che derivano da UIElement, gli oggetti Shape possono essere utilizzati nei pannelli e nella maggior parte dei controlli. Il pannello Canvas è particolarmente indicato per la creazione di disegni complessi, poiché supporta il posizionamento assoluto degli oggetti figlio.

La classe Line consente di disegnare una riga tra due punti. Nell'esempio riportato di seguito vengono illustrate molte modalità per specificare le coordinate della riga e le proprietà del tratto.

<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
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)

// 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
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);

Nell'immagine riportata di seguito viene illustrato Line sottoposto a rendering.

Illustrazione di Line

Anche se la classe Line fornisce una proprietà Fill, l'impostazione di tale proprietà non ha effetto poiché un oggetto Line non dispone di area.

Un'altra forma comune è Ellipse. Creare un oggetto Ellipse definendo le proprietà Width e Height della forma. Per disegnare un cerchio, specificare un oggetto Ellipse i cui valori Width e Height siano uguali.

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


Imports Microsoft.VisualBasic
Imports System
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
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;
        }

    }
}

Nell'immagine riportata di seguito viene illustrato un esempio di Ellipse sottoposto a rendering.

Illustrazione di Ellipse

Utilizzo di percorsi e geometrie

La classe Path consente di disegnare curve e forme complesse. Queste curve e forme vengono descritte utilizzando oggetti Geometry. Per utilizzare Path, creare un oggetto Geometry e utilizzarlo per impostare la proprietà Data dell'oggetto Path.

Sono disponibili numerosi oggetti Geometry tra cui scegliere. Le classi LineGeometry, RectangleGeometry e EllipseGeometry descrivono forme relativamente semplici. Per creare forme più complesse o curve, utilizzare un oggetto PathGeometry.

PathGeometry e PathSegments

Gli oggetti PathGeometry sono composti da uno o più oggetti PathFigure, ciascuno dei quali rappresenta una figura o forma diversa. Ciascun oggetto PathFigure è a sua volta composto da uno o più oggetti PathSegment, ognuno dei quali rappresenta una parte collegata della figura o forma. I tipi di segmento comprendono: LineSegment, BezierSegment e ArcSegment.

Nell'esempio riportato di seguito, viene utilizzato un oggetto Path per disegnare una curva di Bézier quadratica.

<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>

Nell'immagine riportata di seguito viene illustrata la forma sottoposta a rendering.

Illustrazione di Path

Per ulteriori informazioni su PathGeometry e sulle altre classi Geometry, vedere Cenni preliminari sulle classi Geometry.

Sintassi abbreviata XAML

In Extensible Application Markup Language (XAML), è possibile utilizzare anche una sintassi abbreviata speciale per descrivere un oggetto Path. Nell'esempio riportato di seguito, viene utilizzata la sintassi abbreviata per disegnare una forma complessa.

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

Nell'immagine riportata di seguito viene illustrato Path sottoposto a rendering.

Illustrazione di Path

La stringa di attributo Data inizia con il comando "moveto", indicato da M, mediante il quale viene stabilito un punto di partenza per il percorso nel sistema di coordinate dell'oggetto Canvas. Nei parametri di dati di Path viene fatta distinzione tra maiuscole e minuscole. La lettera M maiuscola indica un percorso assoluto per il nuovo punto corrente. Una lettera m minuscola indica le coordinate relative. Il primo segmento è una curva di Bézier cubica che inizia in corrispondenza del punto (100,200) e termina in corrispondenza del punto (400,175) e viene disegnata utilizzando i due punti di controllo (100,25) e (400,350). Questo segmento è indicato dal comando C nella stringa di attributo Data. Anche in questo caso, la lettera C maiuscola indica un percorso assoluto, mentre la lettera c minuscola indica un percorso relativo.

Il secondo segmento inizia con un comando orizzontale assoluto "lineto" H, che specifica una riga disegnata dal punto finale del sottopercorso precedente (400,175) a un nuovo punto finale (280,175). Poiché si tratta di un comando orizzontale "lineto", il valore specificato è una coordinata x.

Per la sintassi completa del percorso, vedere il riferimento Data e Procedura: creare una forma tramite un oggetto PathGeometry.

Disegno di oggetti Shape

Gli oggetti Brush vengono utilizzati per creare le proprietà Stroke e Fill di una forma. Nell'esempio riportato di seguito, vengono specificati il tratto e il riempimento di un oggetto Ellipse. Si noti che un input valido per le proprietà del pennello può essere rappresentato da una parola chiave o da un valore di colore esadecimale. Per ulteriori informazioni sulle parole chiave di colore disponibili, vedere le proprietà della classe Colors nello spazio dei nomi System.Windows.Media.

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

Nell'immagine riportata di seguito viene illustrato l'oggetto Ellipse sottoposto a rendering.

Ellisse

In alternativa, è possibile utilizzare la sintassi degli elementi delle proprietà per creare in modo esplicito un oggetto SolidColorBrush per disegnare la forma con un colore a tinta unita.

<!-- 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>

Nell'immagine riportata di seguito viene illustrata la forma sottoposta a rendering.

Illustrazione di SolidColorBrush

Inoltre, è possibile disegnare il tratto o il riempimento di una forma con sfumature, immagini, pattern e così via. Per ulteriori informazioni, vedere Cenni sul disegno con colori a tinta unita e sfumature.

Oggetti Shape allungabili

Le classi Line, Path, Polygon, Polyline e Rectangle dispongono tutte di una proprietà Stretch. Questa proprietà determina la modalità in cui il contenuto di un oggetto Shape (forma da disegnare) viene allungato per riempire lo spazio del layout di Shape. Lo spazio del layout di un oggetto Shape è la quantità di spazio allocato a Shape dal sistema di layout, tramite un'impostazione esplicita di Width e Height o tramite le impostazioni di HorizontalAlignment e VerticalAlignment. Per ulteriori informazioni sul layout in Windows Presentation Foundation, vedere i cenni preliminari in Sistema di layout.

La proprietà Stretch accetta uno dei seguenti valori:

  • None: il contenuto dell'oggetto Shape non viene allungato.

  • Fill: il contenuto dell'oggetto Shape viene allungato per riempire lo spazio del layout. Le proporzioni non vengono mantenute.

  • Uniform: il contenuto dell'oggetto Shape viene allungato il più possibile per riempire lo spazio del layout mantenendo le proporzioni originali.

  • UniformToFill: il contenuto dell'oggetto Shape viene allungato il più possibile per riempire completamente lo spazio del layout mantenendo le proporzioni originali.

Si noti che, quando il contenuto di un oggetto Shape viene allungato, la struttura dell'oggetto Shape viene disegnata dopo l'allungamento.

Nell'esempio riportato di seguito viene utilizzato un oggetto Polygon per disegnare un triangolo molto piccolo da (0,0) a (0,1) a (1,1). Le proprietà Width e Height dell'oggetto Polygon vengono impostate su 100 e la proprietà Stretch viene impostata su Fill. Di conseguenza, il contenuto dell'oggetto Polygon (triangolo) viene allungato per riempire lo spazio più ampio.

...
<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;
...

Trasformazione degli oggetti Shape

La classe Transform fornisce i mezzi per trasformare le forme su un piano bidimensionale. I diversi tipi di trasformazione includono la rotazione (RotateTransform),il ridimensionamento (ScaleTransform), l'inclinazione (SkewTransform) e la traslazione (TranslateTransform).

Una trasformazione comune da applicare a una forma è una rotazione. Per ruotare una forma, creare un oggetto RotateTransform e specificarne la proprietà Angle. Una proprietà Angle pari a 45 consente di ruotare l'elemento di 45 gradi in senso orario; un angolo di rotazione pari a 90 consente di ruotare l'elemento di 90 gradi in senso orario e così via. Impostare le proprietà CenterX e CenterY per controllare il punto in cui viene ruotato l'elemento. Questi valori di proprietà sono espressi nello spazio delle coordinate dell'elemento trasformato. CenterX e CenterY sono impostati sul valore predefinito 0 (zero). Infine, applicare RotateTransform all'elemento. Per evitare che la trasformazione influisca sul layout, impostare la proprietà RenderTransform della forma.

Nell'esempio riportato di seguito, viene utilizzato RotateTransform per ruotare una forma di 45 gradi rispetto all'angolo in alto a sinistra della forma stessa (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>

Nell'esempio successivo, un'altra forma viene ruotata di 45 gradi, ma in questo caso rispetto al punto (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>

Nell'immagine riportata di seguito vengono illustrati i risultati dell'applicazione delle due trasformazioni.

Rotazioni di 45 gradi con punti centrali diversi

Negli esempi precedenti, è stata applicata una sola trasformazione a ogni oggetto Shape. Per applicare più trasformazioni a una forma (o a qualsiasi altro elemento dell'interfaccia utente), utilizzare un oggetto TransformGroup.

Vedere anche

Concetti

Ottimizzazione delle prestazioni: grafica bidimensionale e creazione di immagini

Cenni sul disegno con colori a tinta unita e sfumature

Cenni preliminari sulle classi Geometry

Procedura dettagliata: introduzione a WPF

Cenni preliminari sull'animazione