Cenni preliminari sulle classi Geometry

Questa panoramica descrive come usare le classi Windows Presentation Foundation (WPF) Geometry per descrivere le forme. In questo argomento vengono inoltre contrastete le differenze tra Geometry oggetti ed Shape elementi.

Definizione di Geometry

La Geometry classe e le classi che ne derivano, ad esempio EllipseGeometry, PathGeometrye CombinedGeometry, consentono di descrivere la geometria di una forma 2D. Queste descrizioni geometriche hanno molti usi, come la definizione di una forma da disegnare sullo schermo o la definizione di aree di hit test e di ritaglio. È anche possibile usare un oggetto Geometry per definire un tracciato di animazione.

Geometry gli oggetti possono essere semplici, ad esempio rettangoli e cerchi o compositi, creati da due o più oggetti geometry. È possibile creare geometrie più complesse usando le PathGeometry classi e StreamGeometry , che consentono di descrivere archi e curve.

Poiché è Geometry un tipo di Freezable, Geometry gli oggetti forniscono diverse funzionalità speciali: possono essere dichiarate come risorse, condivise tra più oggetti, rese di sola lettura per migliorare le prestazioni, clonate e rese thread-safe. Per altre informazioni sulle diverse funzionalità fornite dagli Freezable oggetti, vedere Cenni preliminari sugli oggetti Freezable.

Geometrie e forme

Le Geometry classi e Shape sembrano simili in quanto descrivono entrambe le forme 2D (confrontare EllipseGeometry e Ellipse ad esempio), ma esistono differenze importanti.

Per uno, la Geometry classe eredita dalla Freezable classe mentre la Shape classe eredita da FrameworkElement. Poiché sono elementi, Shape gli oggetti possono eseguire il rendering di se stessi e partecipare al sistema di layout, mentre Geometry gli oggetti non possono.

Anche se Shape gli oggetti sono più facilmente utilizzabili rispetto agli Geometry oggetti, Geometry gli oggetti sono più versatili. Mentre un Shape oggetto viene usato per eseguire il rendering della grafica 2D, è possibile usare un Geometry oggetto per definire l'area geometrica per la grafica 2D, definire un'area per ritagliare o definire un'area per l'hit testing, ad esempio.

Classe Path di Shape

Una Shapeclasse , in Path realtà usa un Geometry oggetto per descriverne il contenuto. Impostando la proprietà di con un Geometry oggetto e impostandone Fill le proprietà e Stroke , è possibile eseguire il Data rendering di un oggetto Geometry.Path

Proprietà comuni che richiedono un oggetto Geometry

Come indicato nelle sezioni precedenti, gli oggetti Geometry possono essere usati con altri oggetti per vari scopi, ad esempio il disegno di forme, l'animazione e il ritaglio. Nella tabella seguente sono elencate diverse classi con proprietà che accettano un Geometry oggetto .

Tipi di oggetti Geometry semplici

La classe base per tutte le geometrie è la classe Geometryastratta . Le classi che derivano dalla Geometry classe possono essere raggruppate approssimativamente in tre categorie: geometrie semplici, geometrie di percorso e geometrie composite.

Le classi geometry semplici includono LineGeometry, RectangleGeometrye e EllipseGeometry vengono usate per creare forme geometriche di base, ad esempio linee, rettangoli e cerchi.

  • Un LineGeometry oggetto viene definito specificando il punto iniziale della riga e il punto finale.

  • Un RectangleGeometry oggetto viene definito con una Rect struttura che specifica la relativa posizione relativa e l'altezza e la larghezza. È possibile creare un rettangolo arrotondato impostando le RadiusX proprietà e RadiusY .

  • Un EllipseGeometry oggetto è definito da un punto centrale, un raggio x e un raggio y. Gli esempi seguenti mostrano come creare geometrie semplici per il rendering e per il ritaglio.

Queste stesse forme, così come forme più complesse, possono essere create usando un PathGeometry oggetto o combinando oggetti geometry insieme, ma queste classi forniscono un mezzo più semplice per produrre queste forme geometriche di base.

Nell'esempio seguente viene illustrato come creare ed eseguire il rendering di un oggetto LineGeometry. Come indicato in precedenza, un Geometry oggetto non è in grado di disegnare se stesso, quindi nell'esempio viene utilizzata una Path forma per eseguire il rendering della linea. Poiché una riga non ha alcuna area, l'impostazione della Fill proprietà dell'oggetto Path non avrà alcun effetto; vengono invece specificate solo le Stroke proprietà e StrokeThickness . L'immagine seguente illustra l'output dell'esempio.

A LineGeometry
Un oggetto LineGeometry disegnato da (10,20) a (100,130)

<Path Stroke="Black" StrokeThickness="1" >
  <Path.Data>
    <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  </Path.Data>
</Path>
LineGeometry myLineGeometry = new LineGeometry();
myLineGeometry.StartPoint = new Point(10,20);
myLineGeometry.EndPoint = new Point(100,130);

Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myLineGeometry;

Nell'esempio seguente viene illustrato come creare ed eseguire il rendering di un oggetto EllipseGeometry. Gli esempi impostano l'oggetto dell'oggetto CenterEllipseGeometry sul punto 50,50 e il raggio x e il raggio y sono entrambi impostati su 50, che crea un cerchio con un diametro di 100. L'interno dell'ellisse viene disegnato assegnando un valore alla proprietà Fill dell'elemento Path, in questo caso Gold. L'immagine seguente illustra l'output dell'esempio.

An EllipseGeometry
Un oggetto EllipseGeometry tracciato a (50,50)

<Path Fill="Gold" Stroke="Black" StrokeThickness="1">
  <Path.Data>
    <EllipseGeometry Center="50,50" RadiusX="50" RadiusY="50" />
  </Path.Data>
</Path>
EllipseGeometry myEllipseGeometry = new EllipseGeometry();
myEllipseGeometry.Center = new Point(50, 50);
myEllipseGeometry.RadiusX = 50;
myEllipseGeometry.RadiusY = 50;

Path myPath = new Path();
myPath.Fill = Brushes.Gold;
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myEllipseGeometry;

Nell'esempio seguente viene illustrato come creare ed eseguire il rendering di un oggetto RectangleGeometry. La posizione e le dimensioni del rettangolo sono definite da una Rect struttura. La posizione è 50,50 e l'altezza e la larghezza sono entrambe 25; viene creato un quadrato. L'immagine seguente illustra l'output dell'esempio.

A RectangleGeometry
Un oggetto RectangleGeometry tracciato a 50,50

<Path Fill="LemonChiffon" Stroke="Black" StrokeThickness="1">
  <Path.Data>
    <RectangleGeometry Rect="50,50,25,25" />
  </Path.Data>
</Path>
RectangleGeometry myRectangleGeometry = new RectangleGeometry();
myRectangleGeometry.Rect = new Rect(50,50,25,25);

Path myPath = new Path();
myPath.Fill = Brushes.LemonChiffon;
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myRectangleGeometry;

Nell'esempio seguente viene illustrato come usare come EllipseGeometry area di ritaglio per un'immagine. Un Image oggetto viene definito con un Width valore pari a 200 e un Height valore pari a 150. Un EllipseGeometry oggetto con valore RadiusX 100, un RadiusY valore pari a 75 e un Center valore pari a 100.75 viene impostato sulla Clip proprietà dell'immagine. Verrà visualizzata solo la parte dell'immagine che è all'interno dell'area dell'ellisse. L'immagine seguente illustra l'output dell'esempio.

An Image with and without clipping
Oggetto EllipseGeometry usato per ritagliare un controllo Image

<Image
  Source="sampleImages\Waterlilies.jpg"
  Width="200" Height="150" HorizontalAlignment="Left">
  <Image.Clip>
    <EllipseGeometry
      RadiusX="100"
      RadiusY="75"
      Center="100,75"/>
  </Image.Clip>
</Image>

// Create the image to clip.
Image myImage = new Image();
Uri imageUri =
    new Uri(@"C:\\Documents and Settings\\All Users\\Documents\My Pictures\\Sample Pictures\\Water lilies.jpg", UriKind.Relative);
myImage.Source = new BitmapImage(imageUri);
myImage.Width = 200;
myImage.Height = 150;
myImage.HorizontalAlignment = HorizontalAlignment.Left;

// Use an EllipseGeometry to define the clip region.
EllipseGeometry myEllipseGeometry = new EllipseGeometry();
myEllipseGeometry.Center = new Point(100, 75);
myEllipseGeometry.RadiusX = 100;
myEllipseGeometry.RadiusY = 75;
myImage.Clip = myEllipseGeometry;

Geometrie di tracciato

La PathGeometry classe e il suo equivalente leggero, la StreamGeometry classe , forniscono i mezzi per descrivere più figure complesse composte da archi, curve e linee.

Al centro di un PathGeometry oggetto è una raccolta di PathFigure oggetti, quindi denominata perché ogni figura descrive una forma discreta nell'oggetto PathGeometry. Ognuno PathFigure di essi è costituito da uno o più PathSegment oggetti, ognuno dei quali descrive un segmento della figura.

Esistono diversi tipi di segmenti.

Tipo di segmento Descrizione Esempio
ArcSegment Crea un arco ellittico tra due punti. Creare un arco ellittico.
BezierSegment Crea una curva di Bézier cubica tra due punti. Creare una curva di Bézier cubica.
LineSegment Crea una linea tra due punti. Creare un oggetto LineSegment in un oggetto PathGeometry
PolyBezierSegment Crea una serie di curve di Bézier cubiche. Vedere la PolyBezierSegment pagina del tipo.
PolyLineSegment Crea una serie di linee. Vedere la PolyLineSegment pagina del tipo.
PolyQuadraticBezierSegment Crea una serie di curve di Bézier quadratiche. Vedere la PolyQuadraticBezierSegment pagina.
QuadraticBezierSegment Crea una curva di Bézier quadratica. Creare una curva di Bézier quadratica.

I segmenti all'interno di un PathFigure oggetto vengono combinati in una singola forma geometrica con il punto finale di ogni segmento che rappresenta il punto iniziale del segmento successivo. La StartPoint proprietà di un PathFigure oggetto specifica il punto da cui viene disegnato il primo segmento. Ogni segmento successivo inizia in corrispondenza del punto finale del segmento precedente. Ad esempio, una linea verticale da 10,50 a 10,150 può essere definita impostando la StartPoint proprietà su 10,50 e creando un LineSegment oggetto con un'impostazione Point di proprietà di 10,150.

Nell'esempio seguente viene creato un oggetto semplice PathGeometry costituito da un singolo PathFigure oggetto con un LineSegment oggetto e viene visualizzato usando un Path elemento . L'oggetto è impostato su 10,20 e viene definito un LineSegment oggetto con un punto finale di 100,130.PathFigureStartPoint La figura seguente mostra l'oggetto PathGeometry creato da questo esempio.

A LineGeometry
Un oggetto PathGeometry che contiene un singolo oggetto LineSegment

<Path Stroke="Black" StrokeThickness="1">
  <Path.Data>
    <PathGeometry>
      <PathGeometry.Figures>
        <PathFigure StartPoint="10,20">
          <PathFigure.Segments>
            <LineSegment Point="100,130"/>
          </PathFigure.Segments>
        </PathFigure>
      </PathGeometry.Figures>
    </PathGeometry>
  </Path.Data>
</Path>

// Create a figure that describes a
// line from (10,20) to (100,130).
PathFigure myPathFigure = new PathFigure();
myPathFigure.StartPoint = new Point(10,20);
myPathFigure.Segments.Add(
    new LineSegment(new Point(100,130),
    true /* IsStroked */ ));

/// Create a PathGeometry to contain the figure.
PathGeometry myPathGeometry = new PathGeometry();
myPathGeometry.Figures.Add(myPathFigure);

// Display the PathGeometry.
Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myPathGeometry;

Vale la pena confrontare questo esempio con l'esempio precedente LineGeometry . La sintassi usata per un PathGeometry oggetto è molto più dettagliata di quella usata per un semplice LineGeometrye può avere più senso usare la LineGeometry classe in questo caso, ma la sintassi dettagliata di PathGeometry consente aree geometriche estremamente complesse e complesse.

È possibile creare geometrie più complesse usando una combinazione di PathSegment oggetti.

Nell'esempio seguente viene utilizzato un BezierSegmentoggetto , un LineSegmente un oggetto ArcSegment per creare una forma. L'esempio crea prima una curva di Bézier cubica definendo quattro punti: un punto iniziale, ovvero il punto finale del segmento precedente, un punto finale (Point3) e due punti di controllo (Point1 e Point2). I due punti di controllo di una curva di Beziér cubica si comportano come magneti, ovvero attraggono parti della linea che sarebbe altrimenti una linea retta, producendo una curva. Il primo punto di controllo, Point1, influisce sulla parte iniziale della curva. Il secondo punto di controllo, Point2, influisce sulla parte finale della curva.

Nell'esempio viene quindi aggiunto un LineSegmentoggetto , che viene disegnato tra il punto finale dell'oggetto precedente BezierSegment che lo precedeva al punto specificato dalla relativa LineSegment proprietà.

Nell'esempio viene quindi aggiunto un oggetto ArcSegment, che viene disegnato dal punto finale dell'oggetto precedente LineSegment al punto specificato dalla relativa Point proprietà. L'esempio specifica anche il raggio x e y dell'arco (Size), un angolo di rotazione (RotationAngle), un flag che indica quanto deve essere grande l'angolo dell'arco risultante (IsLargeArc) e un valore che indica in quale direzione viene disegnato l'arco (SweepDirection). La figura seguente mostra la forma creata da questo esempio.

A PathGeometry with an arc.
Oggetto PathGeometry

<Path Stroke="Black" StrokeThickness="1" >
  <Path.Data>
    <PathGeometry>
      <PathGeometry.Figures>
        <PathFigure StartPoint="10,50">
          <PathFigure.Segments>
            <BezierSegment
              Point1="100,0"
              Point2="200,200"
              Point3="300,100"/>
            <LineSegment Point="400,100" />
            <ArcSegment
              Size="50,50" RotationAngle="45"
              IsLargeArc="True" SweepDirection="Clockwise"
              Point="200,100"/>
          </PathFigure.Segments>
        </PathFigure>
      </PathGeometry.Figures>
    </PathGeometry>
  </Path.Data>
</Path>

// Create a figure.
PathFigure myPathFigure = new PathFigure();
myPathFigure.StartPoint = new Point(10,50);
myPathFigure.Segments.Add(
    new BezierSegment(
        new Point(100,0),
        new Point(200,200),
        new Point(300,100),
        true /* IsStroked */  ));
myPathFigure.Segments.Add(
    new LineSegment(
        new Point(400,100),
        true /* IsStroked */ ));
myPathFigure.Segments.Add(
    new ArcSegment(
        new Point(200,100),
        new Size(50,50),
        45,
        true, /* IsLargeArc */
        SweepDirection.Clockwise,
        true /* IsStroked */ ));

/// Create a PathGeometry to contain the figure.
PathGeometry myPathGeometry = new PathGeometry();
myPathGeometry.Figures.Add(myPathFigure);

// Display the PathGeometry.
Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myPathGeometry;

È possibile creare geometrie ancora più complesse usando più PathFigure oggetti all'interno di un oggetto PathGeometry.

Nell'esempio seguente viene creato un PathGeometry oggetto con due PathFigure oggetti, ognuno dei quali contiene più PathSegment oggetti. Nell'esempio PathFigure precedente vengono usati un PathFigure oggetto con e un QuadraticBezierSegment oggetto PolyLineSegment . Un PolyLineSegment oggetto viene definito con una matrice di punti e QuadraticBezierSegment viene definito con un punto di controllo e un punto finale. La figura seguente mostra la forma creata da questo esempio.

A PathGeometry with an arc that includes two PathFigure objects.
Un oggetto PathGeometry con più figure

<Path Stroke="Black" StrokeThickness="1" >
  <Path.Data>
    <PathGeometry>
      <PathGeometry.Figures>
        <PathFigure StartPoint="10,50">
          <PathFigure.Segments>
            <BezierSegment
              Point1="100,0"
              Point2="200,200"
              Point3="300,100"/>
            <LineSegment Point="400,100" />
            <ArcSegment
              Size="50,50" RotationAngle="45"
              IsLargeArc="True" SweepDirection="Clockwise"
              Point="200,100"/>
          </PathFigure.Segments>
        </PathFigure>
        
        <PathFigure StartPoint="10,100">
          <PathFigure.Segments>
            <PolyLineSegment Points="50,100 50,150" />
            <QuadraticBezierSegment Point1="200,200" Point2="300,100"/>
          </PathFigure.Segments>
        </PathFigure>                
      </PathGeometry.Figures>
    </PathGeometry>
  </Path.Data>
</Path>

PathGeometry myPathGeometry = new PathGeometry();

// Create a figure.
PathFigure pathFigure1 = new PathFigure();
pathFigure1.StartPoint = new Point(10,50);
pathFigure1.Segments.Add(
    new BezierSegment(
        new Point(100,0),
        new Point(200,200),
        new Point(300,100),
        true /* IsStroked */ ));
pathFigure1.Segments.Add(
    new LineSegment(
        new Point(400,100),
        true /* IsStroked */ ));
pathFigure1.Segments.Add(
    new ArcSegment(
        new Point(200,100),
        new Size(50,50),
        45,
        true, /* IsLargeArc */
        SweepDirection.Clockwise,
        true /* IsStroked */ ));
myPathGeometry.Figures.Add(pathFigure1);

// Create another figure.
PathFigure pathFigure2 = new PathFigure();
pathFigure2.StartPoint = new Point(10,100);
Point[] polyLinePointArray =
    new Point[]{ new Point(50, 100), new Point(50, 150)};
PolyLineSegment myPolyLineSegment = new PolyLineSegment();
myPolyLineSegment.Points =
    new PointCollection(polyLinePointArray);
pathFigure2.Segments.Add(myPolyLineSegment);
pathFigure2.Segments.Add(
    new QuadraticBezierSegment(
        new Point(200,200),
        new Point(300,100),
        true /* IsStroked */ ));
myPathGeometry.Figures.Add(pathFigure2);

// Display the PathGeometry.
Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myPathGeometry;

StreamGeometry

Analogamente alla PathGeometry classe , un oggetto StreamGeometry definisce una forma geometrica complessa che può contenere curve, archi e linee. A differenza di , PathGeometryil contenuto di un oggetto StreamGeometry non supporta il data binding, l'animazione o la modifica. Usare un oggetto StreamGeometry quando è necessario descrivere una geometria complessa, ma non si vuole che l'overhead di supporto del data binding, dell'animazione o della modifica. A causa della sua efficienza, la StreamGeometry classe è una buona scelta per descrivere gli adornatori.

Per un esempio, vedere Creare forme tramite un oggetto StreamGeometry.

Sintassi di markup del percorso

I PathGeometry tipi e StreamGeometry supportano una sintassi dell'attributo XAML (Extensible Application Markup Language) usando una serie speciale di comandi di spostamento e disegno. Per altre informazioni, vedere Sintassi di markup del tracciato.

Oggetti Geometry composti

È possibile creare oggetti geometry compositi usando un GeometryGroupoggetto , un CombinedGeometryoggetto o chiamando il metodo Combinestatico Geometry .

  • L'oggetto CombinedGeometry e il Combine metodo esegue un'operazione booleana per combinare l'area definita da due geometrie. Geometry gli oggetti senza area vengono eliminati. È possibile combinare solo due Geometry oggetti (anche se queste due geometrie possono essere geometrie composte).

  • La GeometryGroup classe crea un'amalgamazione degli Geometry oggetti che contiene senza combinare la relativa area. È possibile aggiungere un numero qualsiasi di Geometry oggetti a un oggetto GeometryGroup. Per un esempio, vedere Creare una forma composta.

Poiché non eseguono un'operazione di combinazione, l'uso GeometryGroup di oggetti offre vantaggi in termini di prestazioni rispetto all'uso CombinedGeometry di oggetti o del Combine metodo .

Geometrie combinate

La sezione precedente ha menzionato l'oggetto CombinedGeometry e il Combine metodo combinano l'area definita dalle geometrie che contengono. L'enumerazione GeometryCombineMode specifica la modalità di combinazione delle geometrie. I valori possibili per la GeometryCombineMode proprietà sono: Union, Intersect, Excludee Xor.

Nell'esempio seguente un CombinedGeometry oggetto viene definito con una modalità di combinazione di Unione. Entrambi Geometry1 e Geometry2 sono definiti come cerchi dello stesso raggio, ma con centri sfalsati di 50.

<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
  <Path.Data>
    
    <!-- Combines two geometries using the union combine mode. -->
    <CombinedGeometry GeometryCombineMode="Union">
      <CombinedGeometry.Geometry1>
        <EllipseGeometry RadiusX="50" RadiusY="50" Center="75,75" />
      </CombinedGeometry.Geometry1>
      <CombinedGeometry.Geometry2>
        <EllipseGeometry RadiusX="50" RadiusY="50" Center="125,75" />
      </CombinedGeometry.Geometry2>
    </CombinedGeometry>
  </Path.Data>
</Path>

Results of the Union combine mode

Nell'esempio seguente viene definito un oggetto CombinedGeometry con una modalità di combinazione di Xor. Entrambi Geometry1 e Geometry2 sono definiti come cerchi dello stesso raggio, ma con centri sfalsati di 50.

<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
  <Path.Data>
    
    <!-- Combines two geometries using the XOR combine mode. -->
    <CombinedGeometry GeometryCombineMode="Xor">
      <CombinedGeometry.Geometry1>
        <EllipseGeometry RadiusX="50" RadiusY="50" Center="75,75" />
      </CombinedGeometry.Geometry1>
      <CombinedGeometry.Geometry2>
        <EllipseGeometry RadiusX="50" RadiusY="50" Center="125,75" />
      </CombinedGeometry.Geometry2>
    </CombinedGeometry>
  </Path.Data>
</Path>

Results of the Xor combine mode

Per altri esempi, vedere Creare una forma composta e Creare una geometria combinata.

Funzionalità di Freezable

Poiché eredita dalla Freezable classe , la Geometry classe fornisce diverse funzionalità speciali: Geometry gli oggetti possono essere dichiarati come risorse XAML, condivisi tra più oggetti, resi di sola lettura per migliorare le prestazioni, clonate e rese thread-safe. Per altre informazioni sulle diverse funzionalità fornite dagli Freezable oggetti, vedere Cenni preliminari sugli oggetti Freezable.

Altre funzionalità dell'oggetto Geometry

La Geometry classe fornisce anche metodi di utilità utili, ad esempio i seguenti:

Per un elenco completo dei relativi metodi, vedere la Geometry classe .

Vedi anche