移动绘制的线条用鼠标 [英] Moving a drawn line with the mouse

查看:161
本文介绍了移动绘制的线条用鼠标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用鼠标抓住它来移动绘制的线条。

I am trying to move a drawn line by grabbing it with the mouse.

该生产线已经绘制 Graphics.DrawLine(笔p,A点,b点)

有绝对没有与创建的线,并绘制在窗体上的问题。

There is absolutely no problems with creating the Line and drawing it on the form.

我试过:


  • 添加行到的GraphicsPath - 这还不拿捏的OnPaint

  • Adding the line to a GraphicsPath - This does not even draw the line OnPaint.

检查是否 MouseEventArgs e.Location 是对一些基本代数(计算我已经扔掉截至目前)行

Checking if MouseEventArgs e.Location is on the line with some basic algebra (calculations which I have thrown away as of now)

所以,总结一下:我要抢行并拖动某个地方,但我甚至无法检查e.Location甚至是上线,我该怎么做。

So to sum it up: I want to grab the line and drag it somewhere but I can't even check if e.Location even is on the Line, how do I do this?

编辑:?这是当我使用的GraphicsPath的代码看起来

This is how the code looks when I'm using the GraphicsPath.

当我不使用的GraphicsPath我有:

When I don't use the GraphicsPath I have:

if (s.thisShape == ShapeType.Line) {
  g.DrawLine(pen, s.p1, s.p2);
} else { ... }`

在drawingShapes方法。

in the drawingShapes method.

从drawStuff:控件类:

From the drawStuff : Usercontrol class:

private void drawStuff_MouseDown(object sender, MouseEventArgs e)
{
  pointRegion = e.Location;
  for (int i = 0; i < Shapes.Count; i++)
  {
    if (Shapes[i].Region.IsVisible(pointRegion))
    {
      isDragging = true;
      count = i;
      break;
    }
  }
}

private void drawStuff_MouseMove(object sender, MouseEventArgs e)
{
  if (isDragging)
  {
    Shapes[count].moveWithDiff(pointRegion, e.Location);
    pointRegion = e.Location;
    Refresh();
  }
}

private void drawStuff_MouseUp(object sender, MouseEventArgs e)
{
  isDragging = false;
  Refresh();
}

protected override void OnPaint(PaintEventArgs e)
{
  base.OnPaint(e);
  drawShapes(e.Graphics);
}

private void drawShapes(Graphics g)
{
  temporaryPen = pennaLeft;
  foreach (Shape s in Shapes)
  {
    g.FillRegion(temporaryPen, s.Region);
  }
}

从形状:控件类:

public void moveWithDiff(Point pr, Point mp)
{
  Point p = new Point();
  if (this.thisShape == ShapeType.Line)
  {
    p.X = mp.X - pr.X;
    p.Y = mp.Y - pr.Y;
    this.p1.X += p.X;
    this.p1.Y += p.Y;
    this.p2.X += p.X;
    this.p2.Y += p.Y;
  }
  RefreshPath();
}

private void RefreshPath()
{
  gPath = new GraphicsPath();
  switch (thisShape)
  {
    case ShapeType.Line:
      gPath.AddLine(this.p1, this.p2);
      break;
  }
  this.Region = new Region(gPath);
}

现在这还没有划清界线,但与上述if语句中drawingShapes()它绘制完美,但我不能将它拖到其他地方。

Now this doesn't even draw the line, however with said if statement in drawingShapes() It draws perfectly but I can not drag it somewhere else.

推荐答案

让我们从基础开始,渐渐一行屏幕。我创建了一个自定义的类来处理一些我想提供给我的功能这个过程:

Let's start with the basics, getting a line on the screen. I created a custom class to handle some of the functions I want available to me for this process:

public class MyLine
{
    public Pen pen { get; set; }
    public Point Start { get; set; }
    public Point End { get; set; }

    public MyLine(Pen p, Point p1, Point p2)
    {
        pen = p;
        Start = p1;
        End = p2;
    }

    public float slope
    {
        get
        {
            return (((float)End.Y - (float)Start.Y) / ((float)End.X - (float)Start.X));
        }
    }
    public float YIntercept
    {
        get
        {
            return Start.Y - slope*Start.X;
        }
    }

    public bool IsPointOnLine(Point p, int cushion)
    {
        float temp = (slope * p.X + YIntercept);
        if (temp >= (p.Y-cushion) && temp <=(p.Y+cushion))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}



这个类提供了几个帮手功能,这将使我们的生活更轻松。我们有返回斜率和Y轴截距属性,因此我们可以判断某一个点就行。然后,我们提供了一个辅助函数IsPointOnLine(),它的一个点和缓冲。坐垫是用来简单地允许用户点击足够接近该行得到它返回true。

This class provides a few helper functions that will make our life easier. We have properties that return the slope and the Y-intercept, so we can determine if a certain point is on the line. We then provide a helper function IsPointOnLine() that takes a point and a cushion. The cushion is used to simply allow for a user to click close enough to the line to get it to return true.

下面我来实例化线,绘制在窗体的Paint事件:

Next I am going to instantiate the line and draw it in the Form's paint event:

MyLine m;

private void Form1_Load(object sender, EventArgs e)
{
    m= new MyLine(Pens.Black, new Point(20, 20), new Point(40, 40));
}



private void Form1_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawLine(m.pen, m.Start, m.End);     
}

现在,你应该能够运行应用程序,看到一条线,从去20,20 40,40到屏幕上。

Now you should be able to run your application and see a line that goes from 20,20 to 40,40 on the screen.

现在我想要处理与线下鼠标交互,等等的MouseDown,我们会看到,如果点击相交点行,如果它被设置一个标志,并保持我们的变化量从端点。在MouseMove事件,我们将看到如果该行已被点击,但没有公布,并适当重置坐标。在MouseUp事件,我们简单的重置我们的旗帜:

Now I want to handle the mouse interaction with the line, so on MouseDown, we will see if the click point intersects the line and if it is set a flag and keep our deltas from the endpoints. On the MouseMove event, we will see if the line has been clicked but not released and reset the coordinates appropriately. In the MouseUp event, we simple reset our flag:

Point deltaStart;
Point deltaEnd;
bool dragging = false;

private void Form1_MouseDown(object sender, MouseEventArgs e)
{

    if (e.Button == System.Windows.Forms.MouseButtons.Left && m.IsPointOnLine(e.Location, 5))
    {
        dragging = true;
        deltaStart = new Point(m.Start.X - e.Location.X, m.Start.Y - e.Location.Y);
        deltaEnd = new Point(m.End.X - e.Location.X, m.End.Y - e.Location.Y);
    }
}

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    if (dragging && deltaStart != null && deltaEnd != null )
    {
        m.Start = new Point(deltaStart.X + e.Location.X, deltaStart.Y + e.Location.Y);
        m.End = new Point(deltaEnd.X + e.Location.X, deltaEnd.Y + e.Location.Y);
        this.Refresh();
    }
}

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
    dragging = false;
}

现在,你应该能够在该行的5个像素点击并​​将其移动你的鼠标。

Now you should be able to click within 5 pixels of the line and have it move with your mouse.

请注意,有在代码中的一些点需要额外的错误处理,尤其是0个错误处理部门。

Note, there are some spots in the code that need additional error handling, especially to handle division by 0 errors.

这篇关于移动绘制的线条用鼠标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆