You could define your Arrow shape like the following (replace all shown properties with dependency properties. One example shown.). You could then add a IsSelected property and set the selection style with a DataTrigger that watches that property. You could even set up an animation for the selected arrow that way.
public class Arrow : Shape
{
public static readonly DependencyProperty X1Property = DependencyProperty.Register("X1", typeof(double), typeof(Arrow), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));
[TypeConverter(typeof(LengthConverter))]
public double X1
{
get { return (double)base.GetValue(X1Property); }
set { base.SetValue(X1Property, value); }
}
// TODO: Replace with dependency properties
[TypeConverter(typeof(LengthConverter))]
public double X2 { get; set; }
[TypeConverter(typeof(LengthConverter))]
public double Y1 { get; set; }
[TypeConverter(typeof(LengthConverter))]
public double Y2 { get; set; }
[TypeConverter(typeof(LengthConverter))]
public double ArrowWidth { get; set; }
[TypeConverter(typeof(LengthConverter))]
public double ArrowLength { get; set; }
protected override Geometry DefiningGeometry
{
get
{
var geometryGroup = new GeometryGroup();
// Add arrow head
var midPoint = new Point((X1 + X2) / 2.0, (Y1 + Y2) / 2.0);
double dX = (X2 - X1);
double dY = (Y2 - Y1);
double length = Math.Sqrt(dX*dX + dY*dY);
dX /= length;
dY /= length;
var myPathSegmentCollection = new PathSegmentCollection
{
new LineSegment {Point = new Point(midPoint.X - dX * ArrowLength + dY * ArrowWidth/2.0, midPoint.Y - dY * ArrowLength - dX * ArrowWidth/2.0)},
new LineSegment {Point = new Point(midPoint.X - dX * ArrowLength - dY * ArrowWidth/2.0, midPoint.Y - dY * ArrowLength + dX * ArrowWidth/2.0)},
new LineSegment {Point = midPoint},
};
var myPathFigure = new PathFigure {StartPoint = midPoint, Segments = myPathSegmentCollection};
var myPathFigureCollection = new PathFigureCollection {myPathFigure};
var myPathGeometry = new PathGeometry {Figures = myPathFigureCollection};
geometryGroup.Children.Add(myPathGeometry);
// Add line
geometryGroup.Children.Add(new LineGeometry(new Point(X1, Y1), new Point(X2, Y2)));
return geometryGroup;
}
}
}
Update
Added a single example dependency property.