Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>WPF's <code>Geometry</code> classes have all the primitives you need to accomplish this easily, but you will need to do it in code. When I need to do custom lines I usually construct a <code>Drawing</code> based on the <code>Geometry</code>, but in your case you can simply build a <code>Geometry</code> that has three lines in parallel and stroke that.</p> <ol> <li>Start with <code>PathGeometry.CreateFromGeometry()</code> to get a <code>PathGeometry</code> for the input path</li> <li>Use <code>GetWidenedPathGeometry()</code>, passing in the desired spacing, to get a new geometry whose edges correspond to the side lines</li> <li>(optional) Remove segments at the end of the widened geometry, if desired</li> <li>Combine the side line geomerty with original geometry using a <code>CombinedGeometry</code></li> <li>Stroke the combined geometry to get a triple line</li> </ol> <p>More explanation on step 3: The widened geometry has line segments at the end of the original line. This causes a line to be drawn across the end of your line, which actually looks aesthetically pleasing in many situations. If your situation would look better without it, remove it by iterating the side line geometry and removing all line segments that pass through the endpoints of the original path.</p> <p>The above takes about 8 lines of code if you don't strike off the ends, or 15 if you do.</p> <p>A trick to make this convenient is to create an attached property which effectively coerces the <code>Data</code> property of the <code>Path</code> control it is attached to. With such an attached property, all you need to write is:</p> <pre><code>&lt;Path TripleStroke.Enable="true" Data="..." /&gt; </code></pre> <p>If you know how to implement attached properties and register handlers in them, this is a piece of cake. If not, plan on spending several hours learning how to code attached properties to simulate value coercion before implementing the attached property approach.</p> <p><strong>Update</strong></p> <p>The basic technique I describe above can also be extended to allow an arbitrary pattern to be applied along a path. For an example, see custom brushes in the Expression Design tool. There is nothing built into WPF to do this for you, however, so you'll need to create it yourself, and I can tell you from experience that it is a lot of work. Here are the basic steps:</p> <p>First create a method that takes a <code>Geometry</code> an existing <code>Drawing</code>, and some parameters for end caps, etc and creates a new <code>Drawing</code> that repeats the given <code>Drawing</code> along the path given by the <code>Geometry</code>. Then it is easy to draw a stroked path: Create a <code>Drawing</code> to describe the custom stroke, then display the stroke using a <code>DrawingVisual</code> that contains a <code>Binding</code> with a converter that calls your conversion method.</p> <p>To actually implement the conversion method:</p> <ol> <li>Convert the source drawing into a set of <code>GeometryDrawing</code> objects (I also supported <code>ImageDrawing</code> but that is more complicated since you need to use the 3D system to stretch the images). This is done by recursing through <code>DrawingGroup</code> objects, keeping track of transforms as you go, and constructing GeometryDrawings with appropriate transform.</li> <li>Remove portions of geometry in the "end cap" areas of the original drawing and set them aside.</li> <li>Iterate along the path, duplicating the <code>GeometryDrawing</code> objects repeatedly with appropriate coordinate transformations applied to all coordinates in the geometry.</li> <li>Process the "end cap" sections of the geometry using the same procedure.</li> </ol> <p>Also note in step 1 that any <code>GlyphRunDrawings</code> are handled using <code>FormattedText.BuildGeometry</code> to create an equivalent <code>GeometryDrawing</code>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload