参考网上的代码,我要画一个线段和一个与之平行的虚线段,像这样的——————
- - - - - - 我的代码如下:        protected override void GeneratePath()
        {
            bool isLine = true;            _Path = new System.Drawing.Drawing2D.GraphicsPath();
            _Path.AddLine(Location.X + Size.Width, Location.Y, Location.X + Size.Width, Location.Y + Size.Height);            _Path.CloseAllFigures();
            _Path.AddLine(Location.X, Location.Y, Location.X, Location.Y + Size.Height);            for (int i = Location.Y; i < Location.Y + Size.Height; i = i + 2)
            {
                if (isLine)
                {
                    int st = i;
                    int ed = st + 2;
                    if (st + 2 <= Location.Y + Size.Height)
                    {
                        _Path.CloseFigure();
                        Point pStart = new Point(Location.X, st);
                        Point pEnd = new Point(Location.X, ed);
                        _Path.AddLine(pStart, pEnd);
                        _Path.CloseFigure();
                        isLine = false;
                    }
                }
                else
                {
                    isLine = true;
                }            }
            InvalidationArea = Rectangle.Round(_Path.GetBounds());
        }
我想实现等鼠标点击线段和虚线段区域之间的点时,移动图像if (Path.IsVisible(e.Location))
                return true;问题是,当我点击区域之间的点是,上面的这个函数返回的是False。如何才能选中并移动呢???其他代码        public virtual bool HitTest(MouseEventArgs e)
        {
            //we only need the Location of the mouse but by passing
            //the MouseEventArgs, no value copying has to occur.
            //Only the memory reference will be passed            if (isSelected && InvalidationArea.Contains(e.Location))
                return true;
            else if (Path.IsVisible(e.Location))
                return true;            return false;
        }        public virtual EventData MouseDown(MouseEventArgs e)
        {
            eventData.WasHit = HitTest(e);            if (eventData.WasHit)
            {
                isSelected = true;
                if (!(editingOn && !painter.State.AcceptsEditing))
                {
                    mouseOffset = new PointF(Path.GetBounds().X - e.X, Path.GetBounds().Y - e.Y);
                    pntMoveStartPos = Point.Round(Path.GetBounds().Location);
                    pntBitmapPos = pntMoveStartPos;
                    rectOldBounds = GetShapeBounds(false);
                    mouseIsPressed = true;
                    isResizing = (ResizeHandles.HitTest(e.Location));                }
                eventData.NeedsPainted = true;
            }
            else if (isSelected)
            {
                isSelected = false;
                painter.State.IsSelected = false;
                eventData.NeedsPainted = true;
            }
            return eventData;
        }
        public virtual bool MouseMove(MouseEventArgs e)
        {
            if (isSelected && !editingOn && !mouseIsPressed)
            {
                ResizeHandles.HitTest(e.Location);
            }
            doOperation = false;
            if (mouseIsPressed)
            {
                eventData.NeedsPainted = true;
                if (isResizing)
                {
                    Rectangle oldBounds = ResizeHandles.Bounds;//InvalidationArea;
                    Resize(e.Location);
                    blnSuppressInflate = true;
                    InvalidationArea = Rectangle.Union(oldBounds,
                        GetShapeBounds(false));
                    blnSuppressInflate = false;
                    doOperation = true;
                }
                else
                {
                    if (bmpMove == null)
                    {
                        RectangleF rectBounds = Path.GetBounds();
                        Point tmpLocation = Point.Round(rectBounds.Location);
                        Size tmpSize = Size.Round(rectBounds.Size);
                        GeneratePath(new Rectangle(0, 0, (int)rectBounds.Width, (int)rectBounds.Height));                        bmpMove = new Bitmap((int)rectBounds.Width+2, (int)rectBounds.Height+2);
                        Graphics g = Graphics.FromImage(bmpMove);
                        bool blnTemp = painter.PaintFill;
                        painter.PaintFill = false;
                        painter.Paint(g, Path);
                        painter.PaintFill = blnTemp;
                        g.Dispose(); g = null;                        Location = tmpLocation;
                        Size = tmpSize;
                        _Path = null;
                        //sbLog.Append("Init and Paint the drag bitmap...\r\n");
                    }
                    Rectangle oldBounds = new Rectangle(pntBitmapPos, bmpMove.Size);                    pntBitmapPos = new Point((int)(e.X + mouseOffset.X), (int)(e.Y + mouseOffset.Y));
                    InvalidationArea = Rectangle.Union(oldBounds,
                         new Rectangle(pntBitmapPos, bmpMove.Size));
                    doOperation = true;
                   // sbLog.Append("BitmapPos: " + pntBitmapPos.X + "," + pntBitmapPos.Y + ";   Invalidation: " + _InvalidationArea.ToString() + "\r\n");
                }
            }
            return doOperation;
        }

解决方案 »

  1.   

    如果我不用 _Path.CloseFigure() 且画的线是封闭图形,比如矩形,三角形,圆就不存在问题了。就算不封闭像 |_|的也可以。
      

  2.   


    if (InvalidationArea.Contains(e.Location))
                    return true;
    我这样写了,现在没看出来有什么不对的地方,至少可选中,可移动了,但不可旋转,我也用不到旋转。
    谢谢wuyazhe,又是你,还是那个项目,按照你说的,现在正在一步步的慢慢学习GDI+,有了点心得。项目也在进行着,还是我一个人,但有希望了。
      

  3.   

    粘贴如下代码在你窗体的按钮中。点击看效果。using (Graphics g = this.CreateGraphics())
    {
        g.DrawLine(Pens.Black, 75, 100, 125, 290);
        //x平移50个像素,y上平移30个像素
        GraphicsContainer c = g.BeginContainer(new Rectangle(50, -30, Width, Height), new Rectangle(0, 0, Width, Height), GraphicsUnit.Pixel);
        Pen p = new Pen(Color.DarkGray);
        p.DashStyle = DashStyle.DashDot;
        g.DrawLine(p, 75, 100, 125, 290);//基准点已经偏移,你可以按原来坐标再次绘制。就得到平移后的线了。
        p.Dispose();
        g.EndContainer(c);
    }
    你可以下载我资源中的这个例子,gdi+绘图的,非常全面。
    http://download.csdn.net/source/2090762
      

  4.   

    我之前写的一个(广告中的E-Label就是基本这个升级的):
    http://blog.csdn.net/dunao/archive/2009/02/05/3865053.aspx插播广告:)E-Label是一个专业条码标签打印软件.它会让条码标签打印变得更简单.更方便二次开发(.NET)目前此软件在Beta阶段.如果你对些软件有兴趣可以到http://www.ync-tech.com下截Beta版本
      

  5.   

    一样,我也是一个人,项目也应用到GDI+,前段时间刚学,项目基本功能也实现了,有机会可以交流一下,互相学习,共同进步
      

  6.   

    MouseDown事件,需确定按下的位置是否是在你说描绘的区域中,设置参数,斜率什么用数学算一下,点到直线的距离等都可能用到.
      /// <summary>
            ///  已知平行四边形的三点 求第四个点
            ///  假设3个点为A(a1,a2),B(b1,b2),C(c1,c2) 此处选择第三种情况
            ///  第四个点可以是D(b1+c1-a1,b2+c2-a2),D(a1+b1-c1,a2+b2-c2),D(a1+c1-b1,a2+b2-c2)
            /// </summary>
            /// <param name="p1"></param>
            /// <param name="p2"></param>
            /// <param name="p3"></param>
            /// <returns></returns>
            public static Point MovingLinePoint(Point p1, Point p2, Point p3)
            {
                /* 
                 * 平行四边形
                 * 
                 *        ******P1*******************P4*****
                 *             *                    *
                 *           *                    *
                 *     ****P2*******************P3******
                 * 
                 */
                Point p4 = Point.Empty;
                if (!(p1.IsEmpty && p2.IsEmpty && p3.IsEmpty))
                {
                    p4.X = p1.X + p3.X - p2.X;
                    p4.Y = p1.Y + p3.Y - p2.Y;
                }
                return p4;
            }
    这个是移动一条直线的时候判断点的位置.