Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用鼠标移动绘制的线_C#_Winforms_Drag And Drop_Line - Fatal编程技术网

C# 用鼠标移动绘制的线

C# 用鼠标移动绘制的线,c#,winforms,drag-and-drop,line,C#,Winforms,Drag And Drop,Line,我试图用鼠标抓住一条画好的线来移动它 这条线已经用图形绘制。绘制线(笔p,点A,点B) 创建线条并在表单上绘制它绝对没有问题 我试过: 将线条添加到GraphicsPath-这甚至不会在绘制上绘制线条 检查MouseEventArgs e.Location是否与一些基本代数(到目前为止我已经扔掉的计算)相一致 总而言之:我想抓住线并把它拖到某个地方,但我甚至不能检查e.Location是否在线上,我该怎么做 编辑:这是我使用GraphicsPath时代码的外观 当我不使用图形时,我有: if

我试图用鼠标抓住一条画好的线来移动它

这条线已经用
图形绘制。绘制线(笔p,点A,点B)

创建线条并在表单上绘制它绝对没有问题

我试过:

  • 将线条添加到
    GraphicsPath
    -这甚至不会在绘制上绘制线条

  • 检查
    MouseEventArgs e.Location
    是否与一些基本代数(到目前为止我已经扔掉的计算)相一致

总而言之:我想抓住线并把它拖到某个地方,但我甚至不能检查e.Location是否在线上,我该怎么做

编辑:这是我使用GraphicsPath时代码的外观

当我不使用图形时,我有:

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

从drawStuff:Usercontrol类:

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);
}

现在这甚至没有画线,但是使用drawingShapes()中的if语句,它画得非常完美,但我不能将它拖到其他地方。

我建议您创建一个矩形,它是线的宽度和长度,然后您可以使用

if(rectangle.Contains(Point p))
{
   // do your move
}
您还可以对矩形进行充气,以便于抓取:

rectangle.Inflate(1, 1);

我建议您创建一个矩形,即线条的宽度和长度,然后您可以使用

if(rectangle.Contains(Point p))
{
   // do your move
}
您还可以对矩形进行充气,以便于抓取:

rectangle.Inflate(1, 1);

让我们从基础开始,在屏幕上画一条线。我创建了一个自定义类来处理我希望在此过程中可用的一些函数:

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;
        }
    }
}
现在,您应该能够运行应用程序并在屏幕上看到从20,20到40,40的一行

现在我想处理鼠标与直线的交互,在MouseDown上,我们将看到单击点是否与直线相交,是否设置了标志,并使我们的delta远离端点。在MouseMove事件中,我们将查看该行是否已单击但未释放,并适当地重置坐标。在MouseUp事件中,我们只需重置标志:

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像素范围内单击,并用鼠标移动线条


注意,代码中有一些地方需要额外的错误处理,特别是处理0除错误。

让我们从基础开始,在屏幕上画一行。我创建了一个自定义类来处理我希望在此过程中可用的一些函数:

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;
        }
    }
}
现在,您应该能够运行应用程序并在屏幕上看到从20,20到40,40的一行

现在我想处理鼠标与直线的交互,在MouseDown上,我们将看到单击点是否与直线相交,是否设置了标志,并使我们的delta远离端点。在MouseMove事件中,我们将查看该行是否已单击但未释放,并适当地重置坐标。在MouseUp事件中,我们只需重置标志:

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像素范围内单击,并用鼠标移动线条


注意,代码中有些地方需要额外的错误处理,特别是处理0除错误。

@HansPassant我编辑了这个问题,我希望已经足够了。现在,它可以完美地处理其他形状,如矩形和椭圆,它只是不会移动线条,更不用说绘制它们了。@HansPassant我编辑了这个问题,我希望已经足够了。现在,它与其他形状(如矩形和椭圆)完美配合,它只是不会移动线条,更不用说绘制线条了。只需稍作修改,就可以完美配合我的程序!谢谢!:)非常好的解决方法,但是如果要画几条线,你会如何拖动每一条线呢?只需稍作修改就可以适合我的程序,这非常有效!谢谢!:)非常好的解决方法,但是如果要绘制几条线,您将如何拖动它们?