BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Windows Presentation Foundation
.NET 4.0+

WPF Shapes - Path - Path Markup Syntax

The one hundred and thirty-second part of the Windows Presentation Foundation Fundamentals tutorial completes the examination of Paths. This article describes path markup syntax, which provides a shorter way to describe complex paths of lines, arcs and Bézier curves.

Fill Rules

As with other closed shapes, you can set the rule used to determine which areas of a shape should be filled. By default, the shapes will use the Even-Odd Rule. You can also use the Nonzero Rule. I explained the two rules in the Polygon article.

You can set the fill rule using the "F" command, which must be the first in the markup. For the Even-Odd rule, set the parameter value to zero. For the Nonzero rule, use a value of one.

The following XAML adds a rectangle around all of the previous figures and fills the entire shape using the Even-Odd rule.

Data="F0
      M50,50 L100,100 L150,50 H200 V100 Z
      M50,100 A50,25 45 1 0 100,150
      M50,200 Q30,260 100,250
      M130,250 C120,100 170,350 200,200
      M130,120 Q130,180 180,140 T200,160
      M250,30 C300,70 200,70 250,110 S200,110 250,150 S200,180 250,250
      M-10,-10 L300,-10 L300,300 L-10,300 Z"/>

This gives the following results:

Path Markup Syntax with Even Odd fill rule

Let's change the "F" command's parameter to switch to the Nonzero rule:

Data="F1
      M50,50 L100,100 L150,50 H200 V100 Z
      M50,100 A50,25 45 1 0 100,150
      M50,200 Q30,260 100,250
      M130,250 C120,100 170,350 200,200
      M130,120 Q130,180 180,140 T200,160
      M250,30 C300,70 200,70 250,110 S200,110 250,150 S200,180 250,250
      M-10,-10 L300,-10 L300,300 L-10,300 Z"/>

The fill is slightly different using the new fill rule.

Path Markup Syntax with Nonzero fill rule

Whitespace

In the above examples, we've used a mixture of commas, spaces and line breaks to separate the commands and arguments in the markup. In reality, commas and spaces can be used interchangeably. In fact, as long as the markup is not ambiguous, many of the separators can be removed altogether. This can, of course, make the markup very difficult to read.

To demonstrate, replace the Data property with the following code. This gives exactly the same results as in the previous example. The only difference is the removal of delimiting commas and many of the spaces.

Data="F1M50 50L100 100L150 50H200V100ZM50 100A50 25 45 1 0 100 150M50 200Q30 260 100 250
      M130 250C120 100 170 350 200 200M130 120Q130 180 180 140T200 160M250 30C300 70 200
      70 250 110S200 110 250 150S200 180 250 250M-10-10L300-10L300 300L-10 300Z"

StreamGeometry and PathGeometry

When you add path markup syntax directly to the Data property of a Path element, the shapes are rendered using a StreamGeometry object. This is a lightweight class that provides similar results to PathGeometry, whilst being more efficient. However, it is limited because the shape cannot be modified. This means that you cannot adjust the shapes using code, data binding or animation.

If you need to modify the figures after they are created, you can use a PathGeometry object instead. You are still able to use path markup syntax, applied to the Figures property. You cannot set the fill rule from the mini language for PathGeometry. Instead, you use the FillRule property.

To switch to use PathGeometry, you can use the following XAML:

<Path Stroke="Black" StrokeThickness="3" Fill="PaleTurquoise">
    <Path.Data>
        <PathGeometry
            Figures="M50,50 L100,100 L150,50 H200 V100 Z
                     M50,100 A50,25 45 1 0 100,150
                     M50,200 Q30,260 100,250
                     M130,250 C120,100 170,350 200,200
                     M130,120 Q130,180 180,140 T200,160
                     M250,30 C300,70 200,70 250,110 S200,110 250,150 S200,180 250,250
                     M-10,-10 L300,-10 L300,300 L-10,300 Z"/>
    </Path.Data>
</Path>
1 February 2015