Question

I want to draw a line (more accurately, an arrow) on a PictureBox control. (not draw a line to image itself)

Then, I want to grab the line, move it and resize it(change it's X,Y,X',Y') by dragging.

How can I do that?

I think, at first, I should draw a line and make the drawn line as an independent object... but I only have a concept not the practical ones..

Picture below is an example I found but cannot implement.

That's exactly what I want to make. Draw arrows, Move, Resize and Erase.

enter image description here http://www.codeproject.com/Articles/2097/LineTracker-A-CRectTracker-like-Class-for-Lines

Was it helpful?

Solution 2

I have done this and more complicated vector drawing stuff several times in .NET. I won't provide you with the exact code, but rather the sequence of steps you need to follow. Hopefully you can pick up from there:

  1. Create a new UserControl. Name it anything like DrawingCanvas or ArrowsPond or whatever.
  2. Set control's DoubleBuffered property to True for smooth drawing.
  3. Define a global Class (not Structure) named Arrow with two properties Start and End of Point type. Declare a global List(Of Arrow) to store all your arrow locations.
  4. Override OnMouseDown(). Set a global flag named IsMouseDown to True here. Set a global variable of Point type named MouseDownPos to e.Location.
  5. Override OnMouseUp(). If IsMouseDown is True, set it to False and add a new Arrow to your list with Start=MouseDownPos and End=e.Location.
  6. Override OnMouseMove(). If IsMouseDown is True, call Me.Invalidate().
  7. Override OnPaint() and draw all the arrows in your List using Graphics.DrawLine() method.

This was the drawing part. Now to handle resizing part:

  1. In OnMouseMove(), if IsMouseDown is False, check if e.Location is close enough to any of the start or end-points in your List. You could use simple Euclidean Distance for this and set an arbitrary threshold (say 10 pixels) to define "close-enough" in a more objective way. If you find such a point, store its reference in a global variable of Arrow type named ArrowUnderMouse and set cursor shape to Resize to indicate to the user that he can now drag that point. If you do not detect any close point, set ArrowUnderMouse to Nothing and reset cursor back to Default. You'll need one last global variable named IsOnHead of Boolean type to keep track of whether mouse is near the head or tail of the arrow.
  2. In OnMouseMove, if IsMouseDown is True and ArrowUnderMouse is not Nothing then instead of doing the normal stuff I listed above, set the Start or End property of ArrowUnderMouse to e.Location depending on whether IsOnHead and call Invalidate().

This is just the skeleton of what you need to do and there are LOTS of possibilities that you'd like to play with. For drawing arrow-heads, you'll need to play with Pen properties.

OTHER TIPS

You can use the LineShape control to draw horizontal, vertical, or diagonal lines on a form or container, both at design time and at run time.

Imports Microsoft.VisualBasic.PowerPacks


Dim canvas As New ShapeContainer
Dim theLine As New LineShape
' Set the form as the parent of the ShapeContainer.
canvas.Parent = Me
' Set the ShapeContainer as the parent of the LineShape.
theLine.Parent = canvas
' Set the starting and ending coordinates for the line.
theLine.StartPoint = New System.Drawing.Point(0, 0)
theLine.EndPoint = New System.Drawing.Point(640, 480)

Use PictureBox.Position.X, PictureBox.Position.Y, PictureBox1.Size.Height and PictureBox1.Size.Width as X,Y coordinates when setting the StartPoint and EndPoint

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top