先看效果图:

因为公司是做电子白板软件的所以,对InkCanvas的Stroke进行继承,这样既可省去橡皮擦等的开发.
核心是重写DrawCore函数.
DrawEnd 函数是实现笔尾的三角箭头
DrawHead 函数是实现笔头的三角箭头
其实原理也简单,就是使用 PathGeometry 然后设置Pen 的DashStyle
再使用LineSegment 绘制stylusPoint既可。
internal class PathStrokeK : Stroke
{
private static double[] dashs = new double[] { 5.0, 3.0 };
private static Brush EndBrush = Brushes.Red;
private Geometry endGeometry;
private static string EndGeometryString = "M 0,0 L {0},{1} L0,{0}z";
private Size endSize;
private static Brush HeadBrush = Brushes.Green;
private Geometry headGeometry;
private static string HeadGeometryString = "M 0,{1} L {0},0 L{0},{0}z";
private Size headSize;
private static double Ratio = 5.0;
private static double Thickness = 3.0;
public PathStrokeK(StylusPointCollection spc)
: base(spc)
{
string source = string.Format(HeadGeometryString, Thickness * Ratio, (Thickness * Ratio) / 2.0);
string str2 = string.Format(EndGeometryString, Thickness * Ratio, (Thickness * Ratio) / 2.0);
this.headGeometry = Geometry.Parse(source);
this.endGeometry = Geometry.Parse(str2);
this.headSize = new Size(Thickness * Ratio, Thickness * Ratio);
this.endSize = new Size(Thickness * Ratio, Thickness * Ratio);
}
public void AddPoints(IEnumerable<StylusPoint> stylusPoints)
{
foreach (StylusPoint point in stylusPoints)
{
base.StylusPoints.Add(point);
}
}
protected override void DrawCore(DrawingContext dc, DrawingAttributes da)
{
Brush brush = new SolidColorBrush(da.Color);
StylusPointCollection stylusPoints = base.StylusPoints;
if ((dashs == null) || (dashs.Length == 0))
{
base.DrawCore(dc, da);
}
else if (stylusPoints.Count > 0)
{
Pen pen = new Pen
{
Brush = brush,
Thickness = Thickness,
DashStyle = new DashStyle(dashs, 0.0),
DashCap = PenLineCap.Round,
LineJoin = PenLineJoin.Round,
MiterLimit = 0.0
};
PathGeometry geometry = new PathGeometry();
PathFigure figure = new PathFigure
{
StartPoint = (Point)stylusPoints[0],
IsClosed = false
};
for (int i = 1; i < stylusPoints.Count; i++)
{
figure.Segments.Add(new LineSegment((Point)stylusPoints[i], true));
}
geometry.Figures.Add(figure);
dc.DrawGeometry(null, pen, geometry);
dc.DrawGeometry(brush, null, new EllipseGeometry((Point)stylusPoints[0], Thickness / 2.0, Thickness / 2.0));
dc.DrawGeometry(brush, null, new EllipseGeometry((Point)stylusPoints[stylusPoints.Count - 1], Thickness / 2.0, Thickness / 2.0));
}
if (stylusPoints.Count > 1)
{
if (this.headGeometry != null)
{
this.DrawHead(dc, (Point)stylusPoints[0], (Point)stylusPoints[1], HeadBrush);
}
if (this.endGeometry != null)
{
this.DrawEnd(dc, (Point)stylusPoints[stylusPoints.Count - 1], (Point)stylusPoints[stylusPoints.Count - 2], EndBrush);
}
}
}
private void DrawEnd(DrawingContext dc, Point p0, Point p1, Brush b)
{
Matrix matrix = new Matrix();
matrix.Translate(-this.endSize.Width / 2.0, -this.endSize.Height / 2.0);
Vector vector = new Vector(1.0, 0.0);
Vector vector2 = Point.Subtract(p0, p1);
matrix.Rotate(Vector.AngleBetween(vector, vector2));
matrix.Translate(p0.X, p0.Y);
Geometry geometry = Geometry.Combine(this.endGeometry, Geometry.Empty, GeometryCombineMode.Union, new MatrixTransform(matrix));
dc.DrawGeometry(b, null, geometry);
}
private void DrawHead(DrawingContext dc, Point p0, Point p1, Brush b)
{
Matrix matrix = new Matrix();
matrix.Translate(-this.headSize.Width / 2.0, -this.headSize.Height / 2.0);
Vector vector = new Vector(1.0, 0.0);
Vector vector2 = Point.Subtract(p1, p0);
matrix.Rotate(Vector.AngleBetween(vector, vector2));
matrix.Translate(p0.X, p0.Y);
Geometry geometry = Geometry.Combine(this.headGeometry, Geometry.Empty, GeometryCombineMode.Union, new MatrixTransform(matrix));
dc.DrawGeometry(b, null, geometry);
}
}
浙公网安备 33010602011771号