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