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 a positioning grid and snap line segments to its points in VB .NET
Keywordssnap to, grid, draw, drag
CategoriesGraphics, VB.NET
 
Use mouse event handlers to let the user drag points. This program saves a snapshot of the form's contents before starting a rubberband draw. It uses the snapshot to erase the previously drawn line so it can draw the new one.

The key to snapping to the positioning grid is the SnapToGrid routine that snaps a point to the nearest grid point.

 
Private Const GRID_SPACING As Integer = 10

' 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

Private Sub SaveSnapshot()
    Dim new_bitmap As Bitmap

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

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

    ' Draw the positioning grid.
    DrawGrid(new_bitmap)

    ' 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

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

' Start drawing a rubberband line.
Private Sub picCanvas_MouseDown(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.MouseEventArgs) Handles _
    picCanvas.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_Y1 = e.Y
    SnapToGrid(m_X1, m_Y1)
    m_X2 = m_X1
    m_Y2 = m_Y1
End Sub

' Continue drawing the rubberband line.
Private Sub picCanvas_MouseMove(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.MouseEventArgs) Handles _
    picCanvas.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
    SnapToGrid(m_X2, m_Y2)

    ' Erase the previous line.
    Dim gr As Graphics = picCanvas.CreateGraphics()
    DrawPicture(gr)

    ' Draw the new line directly on the PictureBox.
    gr.DrawLine(Pens.Gray, m_X1, m_Y1, m_X2, m_Y2)
End Sub

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

    ' 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.
    DrawPicture(picCanvas.CreateGraphics())
End Sub

' Snap the point to the grid.
Private Sub SnapToGrid(ByRef X As Integer, ByRef Y As _
    Integer)
    X = GRID_SPACING * CInt(X / GRID_SPACING)
    Y = GRID_SPACING * CInt(Y / GRID_SPACING)
End Sub

' Draw the positioning grid.
Private Sub DrawGrid(ByVal bm As Bitmap)
    For Y As Integer = 0 To bm.Height - 1 Step GRID_SPACING
        For X As Integer = 0 To bm.Width - 1 Step _
            GRID_SPACING
            bm.SetPixel(X, Y, Color.Black)
        Next X
    Next Y
End Sub

' Redraw the picture.
Private Sub picCanvas_Paint(ByVal sender As Object, ByVal e _
    As System.Windows.Forms.PaintEventArgs) Handles _
    picCanvas.Paint
    DrawPicture(e.Graphics)
End Sub

' Make the initial grid.
Private Sub Form1_Load(ByVal sender As Object, ByVal e As _
    System.EventArgs) Handles MyBase.Load
    SaveSnapshot()
End Sub

' Make the new grid.
Private Sub picCanvas_Resize(ByVal sender As Object, ByVal _
    e As System.EventArgs) Handles picCanvas.Resize
    SaveSnapshot()
End Sub
 
For more information on graphics programming in Visual Basic 6, see my book Visual Basic Graphics Programming.
 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated