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
 
 
 
 
 
TitleMake a simple drawing program with a "snap to" grid and rules in Visual Basic .NET
DescriptionThis example shows how to make a simple drawing program with a "snap to" grid and rules in Visual Basic .NET.
Keywordsdrawing, graphics, grid, snap to, snapto, ruler, Visual Basic .NET, VB.NET
CategoriesVB.NET, Graphics
 
When you press the mouse down on the main drawing canvas, the code starts drawing. It sets m_Drawing to True so it can remember that it is drawing. It calls SnapToGrid to snap the current point to the nearest grid point and saves that point. It invalidates the drawing area to redraw and calls ShowMousePosition to show the mouse position in the rulers usin the "drawing" color.
 
' Start drawing a line.
Private Sub picCanvas_MouseDown(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.MouseEventArgs) Handles _
    picCanvas.MouseDown
    ' Only on left mouse down.
    If e.Button <> Windows.Forms.MouseButtons.Left Then _
        Exit Sub
    m_Drawing = True

    ' Start drawing.
    m_X1 = e.X
    m_Y1 = e.Y
    SnapToGrid(m_X1, m_Y1)
    m_X2 = m_X1
    m_Y2 = m_Y1

    picCanvas.Invalidate()
    ShowMousePosition(m_X2, m_Y2)
End Sub
 
Subroutine SnapToGrid snaps a point to the nearest grid location. It determines how many times the grid's size fits into the available canvas size, rounding to the nearest integer. It then multiplies that number by the grid size so get the nearest grid location.
 
' Snap the point to the nearest grid location.
Private Sub SnapToGrid(ByRef X As Integer, ByRef Y As _
    Integer)
    ' If grid snap is off, do nothing.
    If Not m_SnapToGrid Then Exit Sub

    Dim ix As Integer = CInt(X / m_GridX)
    Dim iy As Integer = CInt(Y / m_GridY)
    X = ix * m_GridX
    Y = iy * m_GridY
End Sub
 
Subroutine ShowMousePosition saves a point's coordinates and invalidates the two rulers to make them redraw.
 
' Show the mouse position on the rulers.
Private Sub ShowMousePosition(ByVal X As Integer, ByVal Y _
    As Integer)
    m_MouseX = X
    m_MouseY = Y
    picTopRuler.Invalidate()
    picLeftRuler.Invalidate()
End Sub
 
The main canvas's MouseMove evnet handler saves the current mouse position, snaps it to the grid, shows the mouse position, and redraws the main canvas to show the new line being drawn.
 
' Continue drawing.
Private Sub picCanvas_MouseMove(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.MouseEventArgs) Handles _
    picCanvas.MouseMove
    m_X2 = e.X
    m_Y2 = e.Y
    SnapToGrid(m_X2, m_Y2)

    ' Show the mouse position on the rulers.
    ShowMousePosition(m_X2, m_Y2)

    ' Redraw.
    If m_Drawing Then picCanvas.Invalidate()
End Sub
 
The MouseUp event handler shows the mouse position in the non-drawing color. It then saves the new line segement and redraws to show it in the non-drawing color.
 
' Finish drawing.
Private Sub picCanvas_MouseUp(ByVal sender As Object, ByVal _
    e As System.Windows.Forms.MouseEventArgs) Handles _
    picCanvas.MouseUp
    If Not m_Drawing Then Exit Sub
    m_Drawing = False

    ' Show the mouse position in the non-drawing color.
    ShowMousePosition(m_X2, m_Y2)

    ' Save the new line.
    Dim new_index As Integer = m_Points1.Length
    ReDim Preserve m_Points1(new_index)
    ReDim Preserve m_Points2(new_index)
    m_Points1(new_index) = New PointF(m_X1, m_Y1)
    m_Points2(new_index) = New PointF(m_X2, m_Y2)

    picCanvas.Invalidate()
End Sub
 
The main canvas's Paint event handler clears the canvas. Then if m_ShowGrid is True, it draws the grid. It then draws any existing line segments and finally, if a new line is being drawn, it draws that line.
 
' Draw the lines.
Private Sub picCanvas_Paint(ByVal sender As Object, ByVal e _
    As System.Windows.Forms.PaintEventArgs) Handles _
    picCanvas.Paint
    e.Graphics.Clear(picCanvas.BackColor)

    ' Draw the grid.
    If m_ShowGrid Then
        For x As Integer = 0 To picCanvas.ClientSize.Width _
            Step m_GridX
            For y As Integer = 0 To _
                picCanvas.ClientSize.Height Step m_GridY
                e.Graphics.DrawLine(m_PenGrid, x, y, x + _
                    0.5F, y + 0.5F)
            Next y
        Next x
    End If

    ' Draw existing lines.
    For i As Integer = 0 To m_Points1.Length - 1
        e.Graphics.DrawLine(m_PenOldLine, m_Points1(i), _
            m_Points2(i))
    Next i

    ' Draw the new line.
    If m_Drawing Then
        e.Graphics.DrawLine(m_PenNewLine, m_X1, m_Y1, m_X2, _
            m_Y2)
    End If
End Sub
 
The top ruler's Paint event handler clears the control. It then draws the tick marks using the grid's spacing and giving greater length to every 5 and 10 tick marks. Finally it draws the mouse's position in an appropriate color. The Left ruler's Paint event handler works similarly.
 
' Draw the top ruler.
Private Sub picTopRuler_Paint(ByVal sender As Object, ByVal _
    e As System.Windows.Forms.PaintEventArgs) Handles _
    picTopRuler.Paint
    e.Graphics.Clear(picTopRuler.BackColor)

    Dim y1 As Integer = picTopRuler.ClientSize.Height
    Dim y2 As Integer = (2 * picTopRuler.ClientSize.Height) _
        \ 3
    Dim y3 As Integer = picTopRuler.ClientSize.Height \ 3
    Dim y4 As Integer = 0
    Dim x As Integer = 0
    For i As Integer = 0 To picTopRuler.ClientSize.Width \ _
        m_GridX
        If i Mod 10 = 0 Then
            e.Graphics.DrawLine(m_PenGrid, x, y1, x, y4)
        ElseIf i Mod 5 = 0 Then
            e.Graphics.DrawLine(m_PenGrid, x, y1, x, y3)
        Else
            e.Graphics.DrawLine(m_PenGrid, x, y1, x, y2)
        End If
        x += m_GridX
    Next i

    ' Show the mouse position.
    If m_Drawing Then
        e.Graphics.DrawLine(m_PenRulerDrawing, m_MouseX, _
            y1, m_MouseX, 0)
    Else
        e.Graphics.DrawLine(m_PenRulerNormal, m_MouseX, y1, _
            m_MouseX, 0)
    End If
End Sub
 
Download the example to see additional details such as how the menus let you show or hide the grid and turn grid snapping on and off.

This example is fairly basic and there are lots of other features you could add such as zooming, panning, drawing other shapes, and so forth.

 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated