The PathGeometry class and its light-weight equivalent, the StreamGeometry class, provide the means to describe multiple complex figures composed of arcs, curves, and lines.
At the heart of a PathGeometry is a collection of PathFigure objects, so named because each figure describes a discrete shape in the PathGeometry. Each PathFigure is itself comprised of one or more PathSegment objects, each of which describes a segment of the figure.
There are many types of segments.
The segments within a PathFigure are combined into a single geometric shape with the end point of each segment being the start point of the next segment. The StartPoint property of a PathFigure specifies the point from which the first segment is drawn. Each subsequent segment starts at the end point of the previous segment. For example, a vertical line from 10,50 to 10,150 can be defined by setting the StartPoint property to 10,50 and creating a LineSegment with a Point property setting of 10,150.
The following example creates a simple PathGeometry comprised of a single PathFigure with a LineSegment and displays it using a Path element. The PathFigure object's StartPoint is set to 10,20 and a LineSegment is defined with an end point of 100,130. The following illustration shows the PathGeometry created by this example.
A PathGeometry that contains a single LineSegment
.gif)
<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;
It is worth contrasting this example with the preceding LineGeometry example. The syntax used for a PathGeometry is much more verbose than that used for a simple LineGeometry, and it may make more sense to use the LineGeometry class in this case, but the verbose syntax of the PathGeometry allows for extremely intricate and complex geometric regions.
More complex geometries can be created by using a combination of PathSegment objects.
The next example uses a BezierSegment, a LineSegment, and an ArcSegment to create shape. The example first creates a cubic Bezier curve is by defining four points: a start point, which is the end point of the previous segment, an end point (Point3), and two control points (Point1 and Point2). The two control points of a cubic Bezier curve behave like magnets, attracting portions of what would otherwise be a straight line towards themselves, producing a curve. The first control point, Point1, affects the beginning portion of the curve; the second control point, Point2, affects the ending portion of the curve.
The example then adds a LineSegment, which is drawn between the end point of the preceding BezierSegment that preceded it to the point specified by its LineSegment property.
The example then adds an ArcSegment, which is drawn from the end point of the preceding LineSegment to the point specified by its Point property. The example also specifies the arc's x- and y-radius (Size), a rotation angle (RotationAngle), a flag indicating how large the angle of the resulting arc should be (IsLargeArc), and a value indicating in which direction the arc is drawn (SweepDirection). The following illustration shows the shape created by this example.
A PathGeometry
.gif)
<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;
Even more complex geometries can be created by using multiple PathFigure objects within a PathGeometry.
The following example creates a PathGeometry with two PathFigure objects, each of which contains multiple PathSegment objects. The PathFigure from the above example and a PathFigure with a PolyLineSegment and a QuadraticBezierSegment are used. A PolyLineSegment is defined with an array of points and the QuadraticBezierSegment is defined with a control point and an end point. The following illustration shows the shape created by this example.
A PathGeometry with multiple figures
.gif)
<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
Like the PathGeometry class, a StreamGeometry defines a complex geometric shape that may contain curves, arcs, and lines. Unlike a PathGeometry, the contents of a StreamGeometry do not support data binding, animation, or modification. Use a StreamGeometry when you need to describe a complex geometry but do not want the overhead of supporting data binding, animation, or modification. Because of its efficiency, the StreamGeometry class is a good choice for describing adorners.
For an example, see How to: Create a Shape Using a StreamGeometry.
Path Markup Syntax