One of the more subtle improvements in Silverlight 4 is that we unsealed the Path class. That means you can write a class that behaves like a shape without re-implementing properties like Fill, Stroke, etc. -- just subclass, set Path.Data to render what you want, and provide Measure/Arrange appropriate functionality. (Existing Shapes don't all use the same measure/arrange logic) Here's a sample Triangle class:
public class Triangle : Path { public Triangle() { CreatePathData(0,0); }
private double lastWidth = 0; private double lastHeight = 0; private PathFigure figure;
private void AddPoint(double x, double y) { LineSegment segment = new LineSegment(); segment.Point = new Point(x + 0.5 * StrokeThickness, y + 0.5 * StrokeThickness); figure.Segments.Add(segment); }
private void CreatePathData(double width, double height) { // in order to fit in our layout slot we need to reduce the size of the stroke height -= this.StrokeThickness; width -= this.StrokeThickness;
// needed to avoid a layout loop if (lastWidth == width && lastHeight == height) return; lastWidth = width; lastHeight = height;
var geometry = new PathGeometry(); figure = new PathFigure(); figure.StartPoint = new Point(0 + 0.5 * StrokeThickness, height + 0.5 * StrokeThickness); AddPoint(width, height); AddPoint(width / 2, 0); AddPoint(0, height); figure.IsClosed = true; geometry.Figures.Add(figure); this.Data = geometry; } protected override Size MeasureOverride(Size availableSize) { return availableSize; }
protected override Size ArrangeOverride(Size finalSize) { CreatePathData(finalSize.Width, finalSize.Height); return finalSize; } }
Enjoy!