0

I'm using the answer from another StackOverflow thread here.

My situation is very similar, expect I'm drawing my Lines inside a PictureBox. I modified the above answer by adding a PictureBox to the constructor. I can see that the lines are drawn in my PictureBox, but it won't move.

Am I missing something really obvious here? I've tried a lot of different things, but nothing is working.

LineMover.cs

public class LineMover : Form
{
  public LineMover(PictureBox pb)
  {

    this.DoubleBuffered = true;

    pb.Paint += new PaintEventHandler(LineMover_Paint);
    pb.MouseMove += new MouseEventHandler(LineMover_MouseMove);
    pb.MouseDown += new MouseEventHandler(LineMover_MouseDown);
    pb.MouseUp += new MouseEventHandler(LineMover_MouseUp);

    this.Lines = new List<GraphLine>()
    {
      new GraphLine (10, 10, 100, 200),
      new GraphLine (10, 150, 120, 40),
    };
  }

  void LineMover_MouseUp(object sender, MouseEventArgs e)
  {
    if (Moving != null)
    {
      this.Capture = false;
      Moving = null;
    }
    RefreshLineSelection(e.Location);

  }

  void  LineMover_MouseDown(object sender, MouseEventArgs e)
  {
    RefreshLineSelection(e.Location);
    if (this.SelectedLine != null && Moving == null)
    {
      this.Capture = true;
      Moving = new MoveInfo 
       {
          Line = this.SelectedLine, 
          StartLinePoint = SelectedLine.StartPoint, 
          EndLinePoint = SelectedLine.EndPoint, 
          StartMoveMousePoint = e.Location 
       };
    }
    RefreshLineSelection(e.Location);
  }

  void LineMover_Paint(object sender, PaintEventArgs e)
  {
    e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
    e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
    foreach (var line in Lines)
    {
      var color = line == SelectedLine ? Color.Red : Color.Black;
      var pen = new Pen(color, 2);
      e.Graphics.DrawLine(pen, line.StartPoint, line.EndPoint);
    }
  }
  void LineMover_MouseMove(object sender, MouseEventArgs e)
  {
    if (Moving != null)
    {
      Moving.Line.StartPoint = new PointF(Moving.StartLinePoint.X + e.X - Moving.StartMoveMousePoint.X, Moving.StartLinePoint.Y + e.Y - Moving.StartMoveMousePoint.Y);
      Moving.Line.EndPoint = new PointF(Moving.EndLinePoint.X + e.X - Moving.StartMoveMousePoint.X, Moving.EndLinePoint.Y + e.Y - Moving.StartMoveMousePoint.Y);
    }
    RefreshLineSelection(e.Location);
  }

  private void RefreshLineSelection(Point point)
  {
    var selectedLine = FindLineByPoint(Lines, point);
    if (selectedLine != this.SelectedLine)
    {
      this.SelectedLine = selectedLine;
      this.Invalidate();
    }
    if (Moving != null)
      this.Invalidate();

    this.Cursor =
        Moving != null ? Cursors.Hand :
        SelectedLine != null ? Cursors.SizeAll :
          Cursors.Default;

  }



  public List<GraphLine> Lines = new List<GraphLine>();
  GraphLine SelectedLine = null;
  MoveInfo Moving = null;


  static GraphLine FindLineByPoint(List<GraphLine> lines, Point p)
  {
    var size = 10;
    var buffer = new Bitmap(size * 2, size * 2);
    foreach (var line in lines)
    {
      //draw each line on small region around current point p and check pixel in point p 

      using (var g = Graphics.FromImage(buffer))
      {
        g.Clear(Color.Black);
        g.DrawLine(new Pen(Color.Green, 3), line.StartPoint.X - p.X + size, line.StartPoint.Y - p.Y + size, line.EndPoint.X - p.X + size, line.EndPoint.Y - p.Y + size);
      }

      if (buffer.GetPixel(size, size).ToArgb() != Color.Black.ToArgb())
        return line;
    }
    return null;
  }

  //public static void Main()
  //{
  //  Application.Run(new LineMover());
  //}
}

public class MoveInfo
{
  public GraphLine Line;
  public PointF StartLinePoint;
  public PointF EndLinePoint;
  public Point StartMoveMousePoint;
}
public class GraphLine
{
  public GraphLine(float x1, float y1, float x2, float y2)
  {
    this.StartPoint = new PointF(x1, y1);
    this.EndPoint = new PointF(x2, y2);
  }
  public PointF StartPoint;
  public PointF EndPoint;
}

And my Form1.cs

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        LineMover myLineMover = new LineMover(pictureBox1);
    }
}
Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
deelie
  • 41
  • 1
  • 7
  • _"I modified the above answer by adding a PictureBox to the constructor"_ -- why? What made you think that was a useful thing to do? Do you understand that the `PictureBox` object is still owned by the `Form1` instance? What's the point of putting all the logic related to the `PictureBox` in a completely different form? Do you even ever show that other form? – Peter Duniho Jun 13 '17 at 00:14
  • I added the constructor because my Form1 has multiple PictureBox objects. My apologies as I simplified my code in Form1 above quite a bit. – deelie Jun 13 '17 at 00:20
  • I don't think you understand my question. Your `LineMover` class is a `Form`, but it doesn't ever get shown, nor does it own the `pictureBox1` object. What's the point _of the class_? Showing your code is fine. Code that doesn't make sense is, well...confusing. – Peter Duniho Jun 13 '17 at 00:31
  • Oh, I call Application.Run(new Form1()); in the Main method of my application. – deelie Jun 13 '17 at 00:47
  • _"I call Application.Run(new Form1()); in the Main method of my application"_ -- what's that got to do with the `LineMover` form? I'll ask again (last time): why do you create a `PictureBox` object in one form (`Form1`), and then pass that object to another form (`LineMover`)? Why is `LineMover` a `Form` subclass at all? Do you even ever show it anywhere? – Peter Duniho Jun 13 '17 at 00:54
  • I removed the tag spam - your question is not *about* visual studio, nor *about* VB.NET nor OOP – Ňɏssa Pøngjǣrdenlarp Jun 13 '17 at 01:02
  • I see! I managed to solve my own question. You were right. I ended up having LineMover inherit from PictureBox, and then made my PictureBox a LineMover object instead. – deelie Jun 13 '17 at 01:21

0 Answers0