1、InkCanvas类。

实现画板需要用到InkCanvas。一般情况下不需任何代码就可以在上面画线了。

如果需要设置画笔颜色、笔尖大小等就需要设置DefaultDrawingAttributes,例如:

DrawingAttributes attributes = new DrawingAttributes();
attributes.Color = Colors.Black;
attributes.Height = 50;
attributes.Width = 50;
attributes.FitToCurve = true;

2、在InkCanvas上画直线

方法:在StrokeCollected事件中进行修正,StrokeCollected事件在单个笔画结束后触发。可以取出笔画的起始点(BeginPoint)和终点(EndPoint),然后使用该两点新建笔画即可。

代码如下:

 private void InkCanvas_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e)
        {
            if (e.Stroke.StylusPoints.Count > 1)
            {
                UpdateLine(e.Stroke);
            }
        }
private void UpdateLine(Stroke currentStroke)
        {
            StylusPoint beginPoint = currentStroke.StylusPoints[0];//起始点
            StylusPoint endPoint = currentStroke.StylusPoints.Last();//终点
            packageCanvas.Strokes.Remove(currentStroke);//移除原来的笔画
            List<Point> pointList = new List<Point>();
            pointList.Add(new Point(beginPoint.X, beginPoint.Y));
            pointList.Add(new Point(endPoint.X, endPoint.Y));
            StylusPointCollection point = new StylusPointCollection(pointList);
            Stroke stroke = new Stroke(point);//用两点实现笔画
            stroke.DrawingAttributes = packageCanvas.DefaultDrawingAttributes.Clone();
            InkCanvas.Strokes.Add(stroke);           
}

3、在InkCanvas上画直虚线

方法:还是跟上面一样取起始点和终点,不同点是:在两点间绘制许多点,然后将相邻的两点连接成一个笔画。这样一个直虚线变好了。

代码如下:

private void UpdateLine(Stroke currentStroke)
{
      InkCanvas.Strokes.Remove(currentStroke);//移除原来笔画
                int dotTime = 0;
                int intervalLen=6;//步长
                double lineLen = Math.Sqrt(Math.Pow(beginPoint.X - endPoint.X, 2) + Math.Pow(beginPoint.Y - endPoint.Y, 2));//线的长度
                Point currentPoint = new Point(beginPoint.X, beginPoint.Y);
                double relativaRate = Math.Abs(endPoint.Y - beginPoint.Y) * 1.0 / Math.Abs(endPoint.X - beginPoint.X);
                double angle = Math.Atan(relativaRate) * 180 / Math.PI;//直线的角度大小,无需考虑正负
                int xOrientation = endPoint.X > beginPoint.X ? 1 : -1;//判断新生成点的X轴方向
                int yOrientation = endPoint.Y > beginPoint.Y ? 1 : -1;
                if (lineLen < intervalLen)
                {
                    return;
                }
                while (dotTime * intervalLen < lineLen)
                {
                    double x = currentPoint.X + dotTime * intervalLen * Math.Cos(angle * Math.PI / 180) * xOrientation;
                    double y = currentPoint.Y + dotTime * intervalLen * Math.Sin(angle * Math.PI / 180) * yOrientation; 
                    List<Point> pL = new List<Point>();
                    pL.Add(new Point(x, y));
                    x += intervalLen * Math.Cos(angle * Math.PI / 180) * xOrientation;
                    y += intervalLen * Math.Sin(angle * Math.PI / 180) * yOrientation;
                    pL.Add(new Point(x, y));
                    StylusPointCollection spc = new StylusPointCollection(pL);//相邻两点作为一个笔画
                    Stroke stroke = new Stroke(spc);
                    stroke.DrawingAttributes = packageCanvas.DefaultDrawingAttributes.Clone();
                    InkCanvas.Strokes.Add(stroke);
                    dotTime+=2;
                }
}

4、在InkCanvas上画弯虚线

方法:在InkCanvas_StrokeCollected方法的参数属性中可以获得线上的点的坐标。

2)生成StylusPointCollection collection=currentStroke.StylusPoints,用来存放当前笔画的所有点

2)生成一个List<Point> allPointList,用来存放最终生成的点

2) 将起始点=》allPointList,起始点-》currentPoint

3)遍历collection,IF currentPoint与找到点(item)的距离==步长 THEN item=>allPointList;item=>currentPoint,取下一个点

IF currentPoint与找到点(item)的距离>步长 THEN 在currentPoint与item线上找到一个点,使得与currentPoint的距离=步长,item=>allPointList;item=>currentPoint,继续当前点

IF currentPoint与找到点(item)的距离<步长 取下一个点

代码如下:

private void UpdateLine(Stroke currentStroke)
{
InkCanvas.Strokes.Remove(currentStroke);
                StylusPointCollection collection = currentStroke.StylusPoints;
                List<Point> allSelectedPoint = new List<Point>();
                Point currentPoint = new Point(collection[0].X, collection[0].Y);
                allSelectedPoint.Add(currentPoint);
                for (int i = 0; i < collection.Count; i++)
                {
                    var item = collection[i];
                    double length = Math.Sqrt(Math.Pow(item.X - currentPoint.X, 2) + Math.Pow(item.Y - currentPoint.Y, 2));
                    if ((int)(length + 0.5) == (int)intervalLen || length == intervalLen)
                    {

                        currentPoint = new Point(item.X, item.Y);
                        allSelectedPoint.Add(currentPoint);
                    }
                    else if (length > intervalLen)
                    {
                        double relativaRate = Math.Abs(item.Y - currentPoint.Y) * 1.0 / Math.Abs(item.X - currentPoint.X);
                        double angle = Math.Atan(relativaRate) * 180 / Math.PI;
                        int xOrientation = item.X > currentPoint.X ? 1 : -1;
                        int yOrientation = item.Y > currentPoint.Y ? 1 : -1;
                        double x = currentPoint.X + intervalLen * Math.Cos(angle * Math.PI / 180) * xOrientation;
                        double y = currentPoint.Y + intervalLen * Math.Sin(angle * Math.PI / 180) * yOrientation;
                        currentPoint = new Point(x, y);
                        allSelectedPoint.Add(currentPoint);
                        i--;//很重要,继续当前点
                    }
                }
                for (int j = 0; j < allSelectedPoint.Count; j++)
                {
                    List<Point> p = new List<Point>();
                    p.Add(allSelectedPoint[j]);
                    if (j < allSelectedPoint.Count - 1)
                    {
                        j++;
                    }
                    p.Add(allSelectedPoint[j]);
                    StylusPointCollection spc = new StylusPointCollection(p);
                    Stroke stroke = new Stroke(spc);
                    InkCanvas.Strokes.Add(stroke);
                }
}

以上是测试过的代码,不足之处是:只能在当前笔画完成后在进行修正,因为代码写在InkCanvas_StrokeCollected中。

作者: 顾小石 发表于 2011-01-28 14:55 原文链接

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"