How to: Create a Shape Using a StreamGeometry

StreamGeometry is light-weight alternative to PathGeometry for creating geometric shapes. Use a StreamGeometry when you need to describe a complex geometry but do not want the overhead of supporting data binding, animation, or modification. For example, because of its efficiency, the StreamGeometry class is a good choice for describing adorners.

Example

The following example uses attribute syntax to create a triangular StreamGeometry in XAML.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <StackPanel>
  
    <Path Data="F0 M10,100 L100,100 100,50Z" 
      StrokeThickness="1" Stroke="Black"/>

  </StackPanel>
</Page>

For more information about StreamGeometry attribute syntax, see the Path Markup Syntax page.

Example

The next example uses a StreamGeometry to define a triangle in code. First, the example creates a StreamGeometry, then obtains a StreamGeometryContext and uses it to describe the triangle.

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

namespace SDKSample
{
    // Use StreamGeometry with StreamGeometryContext to define a triangle shape.
    public partial class StreamGeometryTriangleExample : Page
    {
        public StreamGeometryTriangleExample()
        {
            // Create a path to draw a geometry with.
            Path myPath = new Path();
            myPath.Stroke = Brushes.Black;
            myPath.StrokeThickness = 1;

            // Create a StreamGeometry to use to specify myPath.
            StreamGeometry geometry = new StreamGeometry();
            geometry.FillRule = FillRule.EvenOdd;

            // Open a StreamGeometryContext that can be used to describe this StreamGeometry 
            // object's contents.
            using (StreamGeometryContext ctx = geometry.Open())
            {
                
                // Begin the triangle at the point specified. Notice that the shape is set to 
                // be closed so only two lines need to be specified below to make the triangle.
                ctx.BeginFigure(new Point(10, 100), true /* is filled */, true /* is closed */);

                // Draw a line to the next specified point.
                ctx.LineTo(new Point(100, 100), true /* is stroked */, false /* is smooth join */);

                // Draw another line to the next specified point.
                ctx.LineTo(new Point(100, 50), true /* is stroked */, false /* is smooth join */);
            }

            // Freeze the geometry (make it unmodifiable)
            // for additional performance benefits.
            geometry.Freeze();

            // Specify the shape (triangle) of the Path using the StreamGeometry.
            myPath.Data = geometry;

            // Add path shape to the UI.
            StackPanel mainPanel = new StackPanel();
            mainPanel.Children.Add(myPath);
            this.Content = mainPanel;
        }
    }
}

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

Namespace SDKSample
	' Use StreamGeometry with StreamGeometryContext to define a triangle shape.
	Partial Public Class StreamGeometryTriangleExample
		Inherits Page
		Public Sub New()
			' Create a path to draw a geometry with.
			Dim myPath As New Path()
			myPath.Stroke = Brushes.Black
			myPath.StrokeThickness = 1

			' Create a StreamGeometry to use to specify myPath.
			Dim geometry As New StreamGeometry()
			geometry.FillRule = FillRule.EvenOdd

			' Open a StreamGeometryContext that can be used to describe this StreamGeometry 
			' object's contents.
			Using ctx As StreamGeometryContext = geometry.Open()

				' Begin the triangle at the point specified. Notice that the shape is set to 
				' be closed so only two lines need to be specified below to make the triangle.
				ctx.BeginFigure(New Point(10, 100), True, True) ' is closed  -  is filled 

				' Draw a line to the next specified point.
				ctx.LineTo(New Point(100, 100), True, False) ' is smooth join  -  is stroked 

				' Draw another line to the next specified point.
				ctx.LineTo(New Point(100, 50), True, False) ' is smooth join  -  is stroked 
			End Using

			' Freeze the geometry (make it unmodifiable)
			' for additional performance benefits.
			geometry.Freeze()

			' Specify the shape (triangle) of the Path using the StreamGeometry.
			myPath.Data = geometry

			' Add path shape to the UI.
			Dim mainPanel As New StackPanel()
			mainPanel.Children.Add(myPath)
			Me.Content = mainPanel
		End Sub
	End Class
End Namespace

Example

The next example creates a method that uses a StreamGeometry and StreamGeometryContext to define a geometric shape based on specified parameters.

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

namespace SDKSample
{
    public partial class StreamGeometryExample : Page
    {
        public StreamGeometryExample()
        {
            // Create a path to draw a geometry with.
            Path myPath = new Path();
            myPath.Stroke = Brushes.Black;
            myPath.StrokeThickness = 1;

            // Create a StreamGeometry to use to specify myPath.
            StreamGeometry theGeometry = BuildRegularPolygon(new Point(200, 200), 200, 8, 0);
            theGeometry.FillRule = FillRule.EvenOdd;

            // Freeze the geometry (make it unmodifiable)
            // for additional performance benefits.
            theGeometry.Freeze();

            // Use the StreamGeometry returned by the BuildRegularPolygon to 
            // specify the shape of the path.
            myPath.Data = theGeometry;

            // Add path shape to the UI.
            StackPanel mainPanel = new StackPanel();
            mainPanel.Children.Add(myPath);
            this.Content = mainPanel;
        }

        StreamGeometry BuildRegularPolygon(Point c, double r, int numSides, double offsetDegree)
        {
            // c is the center, r is the radius,
            // numSides the number of sides, offsetDegree the offset in Degrees.
            // Do not add the last point.

            StreamGeometry geometry = new StreamGeometry();

            using (StreamGeometryContext ctx = geometry.Open())
            {
                ctx.BeginFigure(new Point(), true /* is filled */, true /* is closed */);

                double step = 2 * Math.PI / Math.Max(numSides, 3);
                Point cur = c;

                double a = Math.PI * offsetDegree / 180.0;
                for (int i = 0; i < numSides; i++, a += step)
                {
                    cur.X = c.X + r * Math.Cos(a);
                    cur.Y = c.Y + r * Math.Sin(a);
                    ctx.LineTo(cur, true /* is stroked */, false /* is smooth join */);
                }
            }

            return geometry;
        }
    }
}

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

Namespace SDKSample
	Partial Public Class StreamGeometryExample
		Inherits Page
		Public Sub New()
			' Create a path to draw a geometry with.
			Dim myPath As New Path()
			myPath.Stroke = Brushes.Black
			myPath.StrokeThickness = 1

			' Create a StreamGeometry to use to specify myPath.
			Dim theGeometry As StreamGeometry = BuildRegularPolygon(New Point(200, 200), 200, 8, 0)
			theGeometry.FillRule = FillRule.EvenOdd

			' Freeze the geometry (make it unmodifiable)
			' for additional performance benefits.
			theGeometry.Freeze()

			' Use the StreamGeometry returned by the BuildRegularPolygon to 
			' specify the shape of the path.
			myPath.Data = theGeometry

			' Add path shape to the UI.
			Dim mainPanel As New StackPanel()
			mainPanel.Children.Add(myPath)
			Me.Content = mainPanel
		End Sub

		Private Function BuildRegularPolygon(ByVal c As Point, ByVal r As Double, ByVal numSides As Integer, ByVal offsetDegree As Double) As StreamGeometry
			' c is the center, r is the radius,
			' numSides the number of sides, offsetDegree the offset in Degrees.
			' Do not add the last point.

			Dim geometry As New StreamGeometry()

			Using ctx As StreamGeometryContext = geometry.Open()
				ctx.BeginFigure(New Point(), True, True) ' is closed  -  is filled 

				Dim [step] As Double = 2 * Math.PI / Math.Max(numSides, 3)
				Dim cur As Point = c

				Dim a As Double = Math.PI * offsetDegree / 180.0
				Dim i As Integer = 0
				Do While i < numSides
					cur.X = c.X + r * Math.Cos(a)
					cur.Y = c.Y + r * Math.Sin(a)
					ctx.LineTo(cur, True, False) ' is smooth join  -  is stroked 
					i += 1
					a += [step]
				Loop
			End Using

			Return geometry
		End Function
	End Class
End Namespace

See Also

PathGeometry
StreamGeometry
StreamGeometryContext
Create a Shape by Using a PathGeometry
Geometry Overview