Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
MSDN Visual Basic Community
 
 
 
 
 
 
TitleDraw rubberband lines in VB .NET
Keywordsrubberband, VB.NET, NET, redraw, AutoRedraw
CategoriesGraphics
 
In VB6 and earlier versions of Visual Basic, drawing rubberband lines is relatively straightforward. You set the DrawMode to vbInvert and draw a line. To erase the line, you draw it again. The inverse of the inverse of a pixel is the same as the original pixel so drawing the line twice restores the picture's original pixels.

For some reason, VB .NET doesn't have invert mode drawing, or any other drawing mode for that matter. To draw a rubberband line in VB .NET, you need to make a Bitmap object representing the image. Draw the line on the form. To erase it, copy the stored Bitmap back onto the form.

In the following code, the MouseDown event handler starts the process. It calls subroutine SaveSnapshot and saves the mouse's position in the variables m_X1, m_Y1, m_X2, and m_Y2.

SaveSnapshot makes a new Bitmap and uses it to create a Graphics object attached to the Bitmap.

When the user moves the mouse, the MouseMove event handler calls subroutine DrawForm to erase any previous line. It then uses the DrawLine method to draw a line directly on the form. It draws on the form not the saved Bitmap so the Bitmap doesn't contain that line. The next time the user moves the mouse, the MouseMove event handler calls DrawForm, which displays the Bitmap without the line.

Subroutine DrawForm simply uses DrawImage to draw the saved Bitmap onto the form.

When the user releases the mouse, the MouseUp event handler uses the saved Bitmap's DrawLine method to draw the final line on the saved bitmap. It then calls DrawForm to display the bitmap with the new line.

The final piece of code in this program is the Paint event handler. VB .NET has no AutoRedraw property so if you want the form to display something after it is covered and exposed, you need to handle this explicitly. This program's Paint event handler calls the DrawForm subroutine to redisplay the saved bitmap.

 
' True while we are drawing the new line.
Private m_Drawing As Boolean

' Buffer for erasing rubberband lines.
Private m_BufferBitmap As Bitmap
Private m_BufferGraphics As Graphics

' The mouse position.
Private m_X1 As Integer
Private m_Y1 As Integer
Private m_X2 As Integer
Private m_Y2 As Integer

' Start drawing a rubberband line.
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e _
    As System.Windows.Forms.MouseEventArgs) Handles _
    MyBase.MouseDown
    ' Do nothing if this isn'tthe left mouse button.
    If e.Button <> MouseButtons.Left Then Exit Sub
    m_Drawing = True

    ' Save a snapshot of the form.
    SaveSnapshot()

    ' Save the current mouse position.
    m_X1 = e.X
    m_X2 = e.X
    m_Y1 = e.Y
    m_Y2 = e.Y
End Sub

Private Sub SaveSnapshot()
    Dim new_bitmap As Bitmap

    ' Make a new bitmap that fits the form.
    new_bitmap = New Bitmap(Me.Size.Width, Me.Size.Height, _
        Me.CreateGraphics())
    m_BufferGraphics = Graphics.FromImage(new_bitmap)

    ' Clear the new bitmap.
    m_BufferGraphics.Clear(Me.BackColor)

    ' Copy the existing bitmap's contents into
    ' the new bitmap.
    If Not (m_BufferBitmap Is Nothing) Then
        m_BufferGraphics.DrawImage(m_BufferBitmap, 0, 0)
    End If

    ' Save the new bitmap and graphics objects.
    m_BufferBitmap = new_bitmap
End Sub

' Continue drawing the rubberband line.
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e _
    As System.Windows.Forms.MouseEventArgs) Handles _
    MyBase.MouseMove
    ' Do nothing if we're not drawing.
    If Not m_Drawing Then Exit Sub

    ' Save the new point.
    m_X2 = e.X
    m_Y2 = e.Y

    ' Erase the previous line.
    DrawForm(Me.CreateGraphics())

    ' Draw the new line directly on the form.
    Me.CreateGraphics().DrawLine( _
        Pens.Gray, m_X1, m_Y1, m_X2, m_Y2)
End Sub

' Redraw the saved buffer.
Private Sub DrawForm(ByVal gr As Graphics)
    If Not (m_BufferBitmap Is Nothing) Then _
        gr.DrawImage(m_BufferBitmap, 0, 0)
End Sub

' Finish drawing the new line.
Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e _
    As System.Windows.Forms.MouseEventArgs) Handles _
    MyBase.MouseUp
    ' Do nothing if we're not drawing.
    If Not m_Drawing Then Exit Sub
    m_Drawing = False

    ' Save the new point.
    m_X2 = e.X
    m_Y2 = e.Y

    ' Draw the new line permanently on the buffer.
    m_BufferGraphics.DrawLine( _
        Pens.Blue, m_X1, m_Y1, m_X2, m_Y2)

    ' Redraw to show the new line.
    DrawForm(Me.CreateGraphics())
End Sub

' Redraw the form.
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As _
    System.Windows.Forms.PaintEventArgs) Handles _
    MyBase.Paint
    DrawForm(e.Graphics)
End Sub
 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated