public override void MakeVisual() { if (GeometryEdge.Curve == null) { return; } SetValue(Canvas.LeftProperty, Edge.BoundingBox.Left); SetValue(Canvas.TopProperty, Edge.BoundingBox.Bottom); if (StrokeDashArray == null) { // Note that Draw.CreateGraphicsPath returns a curve with coordinates in graph space. var pathFigure = Draw.CreateGraphicsPath((DrawingEdge.GeometryObject as GeometryEdge).Curve); var pathGeometry = new PathGeometry(); pathGeometry.Figures.Add(pathFigure); Draw.DrawEdgeArrows(pathGeometry, DrawingEdge, FillArrowheadAtSource, FillArrowheadAtTarget); // Apply a translation to bring the coordinates in node space (i.e. top left corner is 0,0). pathGeometry.Transform = new MatrixTransform() { Matrix = new Matrix(1.0, 0.0, 0.0, 1.0, -Edge.BoundingBox.Left, -Edge.BoundingBox.Bottom) }; if (SelectedForEditing && GeometryEdge.UnderlyingPolyline != null) { Draw.DrawUnderlyingPolyline(pathGeometry, this); } var path = new Path() { Data = pathGeometry, StrokeThickness = Math.Max(LineWidth, Edge.Attr.LineWidth), Stroke = EdgeBrush, Fill = EdgeBrush }; Content = path; } else { // A dash array has been specified. I don't want to apply it to both the edge and the arrowheads; for this reason, I'm going to split the drawing in two Path instances. // This is not done in the general case to keep the number of Paths down. var pathFigure = Draw.CreateGraphicsPath((DrawingEdge.GeometryObject as GeometryEdge).Curve); var pathGeometry = new PathGeometry(); pathGeometry.Figures.Add(pathFigure); pathGeometry.Transform = new MatrixTransform() { Matrix = new Matrix(1.0, 0.0, 0.0, 1.0, -Edge.BoundingBox.Left, -Edge.BoundingBox.Bottom) }; if (SelectedForEditing && GeometryEdge.UnderlyingPolyline != null) { Draw.DrawUnderlyingPolyline(pathGeometry, this); } DoubleCollection dc = new DoubleCollection(); foreach (double d in StrokeDashArray) { dc.Add(d); } var path1 = new Path() { Data = pathGeometry, StrokeThickness = Math.Max(LineWidth, Edge.Attr.LineWidth), Stroke = EdgeBrush, Fill = EdgeBrush, StrokeDashArray = dc }; pathGeometry = new PathGeometry(); pathGeometry.Transform = new MatrixTransform() { Matrix = new Matrix(1.0, 0.0, 0.0, 1.0, -Edge.BoundingBox.Left, -Edge.BoundingBox.Bottom) }; Draw.DrawEdgeArrows(pathGeometry, DrawingEdge, FillArrowheadAtSource, FillArrowheadAtTarget); var path2 = new Path() { Data = pathGeometry, StrokeThickness = Math.Max(LineWidth, Edge.Attr.LineWidth), Stroke = EdgeBrush, Fill = EdgeBrush }; var c = new Grid(); c.Children.Add(path1); c.Children.Add(path2); Content = c; } }