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:
- Create a new UserControl. Name it anything like
DrawingCanvas
orArrowsPond
or whatever. - Set control's
DoubleBuffered
property toTrue
for smooth drawing. - Define a global
Class
(notStructure
) namedArrow
with two propertiesStart
andEnd
ofPoint
type. Declare a globalList(Of Arrow)
to store all your arrow locations. - Override
OnMouseDown()
. Set a global flag namedIsMouseDown
toTrue
here. Set a global variable ofPoint
type namedMouseDownPos
toe.Location
. - Override
OnMouseUp()
. IfIsMouseDown
isTrue
, set it toFalse
and add a newArrow
to your list withStart=MouseDownPos
andEnd=e.Location
. - Override
OnMouseMove()
. IfIsMouseDown
isTrue
, callMe.Invalidate()
. - Override
OnPaint()
and draw all the arrows in yourList
usingGraphics.DrawLine()
method.
This was the drawing part. Now to handle resizing part:
- In
OnMouseMove()
, ifIsMouseDown
isFalse
, check ife.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 ofArrow
type namedArrowUnderMouse
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, setArrowUnderMouse
toNothing
and reset cursor back toDefault
. You'll need one last global variable namedIsOnHead
ofBoolean
type to keep track of whether mouse is near the head or tail of the arrow. - In
OnMouseMove
, ifIsMouseDown
isTrue
andArrowUnderMouse
is notNothing
then instead of doing the normal stuff I listed above, set theStart
orEnd
property ofArrowUnderMouse
toe.Location
depending on whetherIsOnHead
and callInvalidate()
.
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.