none
WPF 怎么画虚线和波浪线?? RRS feed

  • 问题

  • //画虚线:(两点:startPoint,endPoint之间画虚线)
    StylusPointCollection pts=new StylusPointCollection();
    pts.Add(new StylusPoint(startPoint.X, startPoint.Y));
    pts.Add(new StylusPoint(endPoint.X, endPoint.Y));
    //设置Pen的Dashstyle可以画出虚线
     DoubleCollection dc = new DoubleCollection();
     dc.Add(2);
     dc.Add(2);
     DashStyle dashstyle = new DashStyle();
     dashstyle.Dashes = dc;
     dashstyle.Offset = 0;
     Pen pen = new Pen
      {
                    StartLineCap = PenLineCap.Round,
                    EndLineCap = PenLineCap.Round,
                    Brush = new SolidColorBrush(drawingAttributes.Color),
                    Thickness = drawingAttributes.Width,
                    DashCap = PenLineCap.Round,
                    DashStyle = dashstyle
    };
    
     drawingContext.DrawLine(pen,
                    new Point(StylusPoints[0].X, StylusPoints[0].Y),
                    new Point(StylusPoints[1].X, StylusPoints[1].Y));
    
    //画波浪线:(两点:startPoint,endPoint之间画波浪线)
    StylusPointCollection pts=new StylusPointCollection();
    //先把这两点之间的线段分成若干等分点
     double x1, y1, x2, y2;
                if (endPoint.X >= startPoint.X)
                {
                    x1 = startPoint.X;
                    x2 = endPoint.X;
                    y1 = startPoint.Y;
                    y2 = endPoint.Y;
    
                }
                else
                {
    
                    x1 = endPoint.X;
                    x2 = startPoint.X;
                    y1 = endPoint.Y;
                    y2 = startPoint.Y;
                }
              
                 if (x2 == x1)
                {
                    double x11, y11, x22, y22;
                    if (endPoint.Y >= startPoint.Y)
                    {
                        x11 = startPoint.X;
                        x22 = endPoint.X;
                        y11 = startPoint.Y;
                        y22 = endPoint.Y;
    
                    }
                    else
                    {
    
                        x11 = endPoint.X;
                        x22 = startPoint.X;
                        y11 = endPoint.Y;
                        y22 = startPoint.Y;
                    }
                    for (double y = y11; y <= y22; y += 5)
                    {
                        pts.Add(new StylusPoint(x1,y));
                    }
                }
                else
               {                            
       for (double x = x1; x <= x2; x += 5 * width)
                    {
                        pts.Add(new StylusPoint(x, y1 + x * (y2 - y1) / (x2 - x1) - x1 * (y2 - y1) / (x2 - x1)));
                    }
                }
    
    //通过没两点之间画ArcSegment 椭圆来画波浪线
    Pen pen = new Pen
                {
                    StartLineCap = PenLineCap.Round,
                    EndLineCap = PenLineCap.Round,
                    Brush = new SolidColorBrush(drawingAttributes.Color),
                    Thickness = drawingAttributes.Width
                };
    
                pathGeomery = new PathGeometry();
                PathSegmentCollection pathCollection = new PathSegmentCollection();       
               for (int i = 1; i < StylusPoints.Count; i++)
                {
                    Size size = new Size(4 *drawingAttributes.Width, 2 * drawingAttributes.Width);
                        if (i % 2 == 0)
                    {
                        pathCollection.Add(new ArcSegment(new Point(StylusPoints[i].X, StylusPoints[i].Y), size, 0, false, SweepDirection.Clockwise, true));
                    }
                    else
                    {
                        pathCollection.Add(new ArcSegment(new Point(StylusPoints[i].X, StylusPoints[i].Y), size, 0, false, SweepDirection.Counterclockwise, true));
                    }
    
                }                  
                PathFigure pathFigure = new PathFigure();
                pathFigure.IsClosed = false;
                pathFigure.StartPoint = new Point(StylusPoints[0].X, StylusPoints[0].Y);
                pathFigure.Segments = pathCollection;
                PathFigureCollection pathFigureCollection = new PathFigureCollection();
                pathFigureCollection.Add(pathFigure);
                pathGeomery.Figures = pathFigureCollection;
                drawingContext.DrawGeometry(BgColor, pen, pathGeomery);


    通过上面的方法在InkCanvas画的曲线,波浪线,撤销再重做之后就变成了起点和终点的一条直线,怎么解决,我知道画虚线的时候只加入了两个点,所以撤销重做之后就是这两点的直线了;画波浪线的时候也是加入了这两点的线段之间的等分点,撤销重做之后把这些点连接也是一条直线的,,,,现在怎么解决这种问题啊??
    • 已编辑 heller灬 2014年11月20日 1:49 编辑
    2014年11月19日 2:04

全部回复

  • 你好 heller灬,

    首先我可能还没理解你的需求,撤销重做的话你重绘不久可以了么?具体的问题在哪里?要不你给贴个截图来描述下?

    我觉得你可以在XAML里面画这些东西的,介绍你一些XAML绘图的方式吧:

    比如首先是虚线:

          <Line X1="10" Y1="10" X2="100" Y2="100" Stroke="Black" StrokeDashArray="2,9" StrokeThickness="2" Margin="10,10,-10,-10" />

    再然后是波浪线:

     <Path Stroke="Red" StrokeThickness="2" >
                <Path.Data>
                    <PathGeometry>
                        <PathGeometry.Figures>
                            <PathFigureCollection>
                                <PathFigure StartPoint="10,100">
                                    <PathFigure.Segments>
                                        <PathSegmentCollection>
                                            <BezierSegment Point1="120,0" 
                                                   Point2="200,200" 
                                                   Point3="300,100" 
                                                   />
                                        </PathSegmentCollection>
                                    </PathFigure.Segments>
                                </PathFigure>
                            </PathFigureCollection>
                        </PathGeometry.Figures>
                    </PathGeometry>
                </Path.Data>
            </Path>

    当然在程序里如果你继续用dashstyle而不知道怎么去配置他们的时候你可以先参看下MSDN文档:

    http://msdn.microsoft.com/en-us/library/system.windows.media.dashstyle(v=vs.110).aspx

    关于波浪线,不太理解你的想法的情况下我就不贴了。



    Barry
    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年11月20日 2:43
    版主
  • 虚线,波浪线我都是已经可以实现的了,但就是撤销重做之后出现了问题,因为我的撤销重做机制是序列化Inkcanvas画板的,其实就是把一个Xaml格式的文本放在一个栈中,

    撤销重做就是取出栈中的xaml,但是保存的Xmal中的直线与曲线就是一条stroke,这个stroke就只有起点和终点,于是呈现出来的就是一条直线了,而不是虚线和波浪线了

    撤销重做之后:


    2014年11月20日 3:43
  • 官方有个例子,你先参照一下官方的代码是怎么写的:

    http://msdn.microsoft.com/en-us/library/vstudio/aa972158(v=vs.90).aspx

    在他的例子里Undo,Redo操作返回的strokecollection是没有问题的,你可以比较一下看看自己代码里有什么问题。



    Barry
    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年11月21日 9:49
    版主
  • 我看了这个例子,他的撤销重做使用的是命令模式,我的撤销重做使用的是备忘录模式;

    因为我的Inkcanvas容器上还有Image,MediaElement等控件,所以选择使用了备忘录模式;

    如果可以使用命令模式,怎么做呢??或者是不需要更改撤销重做的模式,怎么解决这个问题?

    2014年11月22日 3:25