This is one way of doing it.
Public Class Form1
'This flag keeps track of wether we have started to draw a line or not
'if this is the first time the mouse was clicked in the picturebox then the flag value is FALSE
'if this is the second time the mouse was clicked in the picturebox then the flag value is TRUE
Dim Drawing As Boolean
'This flag stores the mousepointer location(SPoint stands for STARTPoint for the line and is X,Y values)
Dim SPoint As Point
'This flag stores the mousepointer location(EPoint stands for ENDPoint for the line and is X,Y values)
Dim EPoint As Point
'This is the history of the lines drawn so far
'HistorySPoint stores the line STARTING points
'HistoryEPoint stores the line END points
Dim HistorySPoint As Generic.List(Of Point)
Dim HistoryEPoint As Generic.List(Of Point)
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
'Tidy up the form level/scope variables
Drawing = Nothing
SPoint = Nothing
EPoint = Nothing
HistoryEPoint = Nothing
HistorySPoint = Nothing
End Sub
'FormLoad Event
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'we set the label to ready to let the user know we are ready
Label1.Text = "Ready"
'we initailise as new STARTPoints collection
HistorySPoint = New Generic.List(Of Point)
'we initailise as new ENDPoints collection
HistoryEPoint = New Generic.List(Of Point)
'show info
MsgBox("To draw a line, click in the picturebox to define a START point" & vbCrLf & "then click again elsewhere to define an END point" & vbCrLf & "On the second click the line will be drawn and listed in the history" & vbCrLf & "To remove a line click on the line in the listbox and then click on the UNDO button.", MsgBoxStyle.Information, "Information.")
End Sub
'DrawLineProcedure - This passes the PENcolor as a parameter
Private Sub DrawLine(ByVal color As System.Drawing.Pen)
'Define a graphics context/canvas (drawing surface)
Dim TheGrafix As System.Drawing.Graphics
'Assign the picturebox context/canvas to the drawing surface
TheGrafix = PictureBox1.CreateGraphics()
'draw the line on the picturebox canvas
'using the PENcolor and the STARTPoint and the ENDPoint of the line
TheGrafix.DrawLine(color, SPoint, EPoint)
'Yidy up after ourselves
TheGrafix.Dispose()
End Sub
Private Sub PictureBox1_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseClick
'If this is the START of a newline then Drawing is always FALSE
'If we have started to draw a line previously with a mouse click then Drawing is always TRUE
'at the end of drawing every line Drawing is reset to FALSE - ready for another line
If Not Drawing Then
'as we are startinga line - set the flag to show as much
Drawing = True
SPoint.X = e.X 'store the mouse X coords in POINT SPoint
SPoint.Y = e.Y 'store the mouse Y coords in POINT SPoint
'update the label to show wehave started to draw a new line
Label1.Text = "Start point mapped, please move mouse to end point and click again"
Else
EPoint.X = e.X 'store the mouse X coords in POINT EPoint
EPoint.Y = e.Y 'store the mouse Y coords in POINT EPoint
'Store both the START and END pooints in the history
HistorySPoint.Insert(ListBox1.Items.Count, SPoint)
HistoryEPoint.Insert(ListBox1.Items.Count, EPoint)
'Add the points to our history listbox for visual confirmation
ListBox1.Items.Insert(ListBox1.Items.Count, "(" & SPoint.X & ", " & SPoint.Y & ") - (" & EPoint.X & ", " & EPoint.Y & ")")
'Physically draw the line by calling the DRAWLINE procedure whilst passing a PENColor
'in this case the color is Black
DrawLine(Pens.Black)
'update the label to show we are ready for the next line
Label1.Text = "Ready"
'Reset the Drawing Flag to FALSE
Drawing = False
End If
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
'Echo the mouse co-ordinates in the label
Label2.Text = "X: " & e.X
Label3.Text = "Y: " & e.Y
End Sub
Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
'THe user has clicked on an line inthe HISTORY listory so ENABLE the UNDO button
'to allow the user to UNDO the selected line
If ListBox1.SelectedIndex <> (-1) Then Button1.Enabled = True
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'The user clicked the undo button
'Redraw all the lines black EXCEPT the selected line
'which is drawn in the same color as the Picturebox BACKCOLOR
'and after that REMOVE the line details from the Points history and the history listbox
Dim intCounta As Integer
Dim intSelIdx As Integer
intSelIdx = ListBox1.SelectedIndex
ListBox1.Items.RemoveAt(intSelIdx)
If HistorySPoint.Count > 0 Then
For intCounta = 0 To HistorySPoint.Count - 1
If intCounta = intSelIdx Then
SPoint = HistorySPoint(intCounta)
EPoint = HistoryEPoint(intCounta)
DrawLine(Pens.White)
Else
SPoint = HistorySPoint(intCounta)
EPoint = HistoryEPoint(intCounta)
DrawLine(Pens.Black)
End If
Next
HistorySPoint.RemoveAt(intSelIdx)
HistoryEPoint.RemoveAt(intSelIdx)
End If
intSelIdx = Nothing
intCounta = Nothing
End Sub
End Class