Search code examples
.netvb.netwinformspen

How to draw a line in VB.NET


I am trying to draw a simple line with VB.NET.

My code is as below, however when I run the code, only the form is shown up! There is no line.

What did I do wrong here?

Public Class Form1
  Dim pen As System.Drawing.Graphics
  Private Sub Form1_Load(ByVal sender As System.Object,
                         ByVal e As System.EventArgs) Handles MyBase.Load
    pen = Me.CreateGraphics()
    pen.DrawLine(Pens.Azure, 10, 10, 20, 20)
  End Sub       
End Class

Solution

  • Basically, what you did wrong was to use the CreateGraphics method.

    This is something that you rarely, if ever, need to do. It's not as if the method is broken, of course. It does exactly what it says: it is documented as doing: returning a Graphics object representing the drawing surface of your form.

    The problem is that whenever your form gets redrawn (which can happen for lots of reasons), the Graphics object basically gets reset. As a result, everything that you drew into the one that you obtained is erased.

    A form is always redrawn when it is first loaded, so using CreateGraphics never makes sense in the Load event handler method. It is also going to be redrawn any time that it is minimized and restored, covered up by another window, or even resized (some of these depend on your operating system, graphics drivers, and your form's properties, but that's beyond the point).

    The only time that you might use CreateGraphics is when you want to show immediate feedback to the user that should not persist across redraws. For example, in the handler for the MouseMove event, when showing feedback for a drag-and-drop.

    So, what is the solution? Always do your drawing inside of the Paint event handler method. That way, it persists across redraws, since a "redraw" basically involves raising the Paint event.

    When the Paint event is raised, the handler is passed an instance of the PaintEventArgs class, which contains a Graphics object that you can draw into.

    So here's what your code should look like:

    Public Class Form1
    
        Protected Overridable Sub OnPaint(e As PaintEventArgs)
            ' Call the base class
            MyBase.OnPaint(e)
    
            ' Do your painting
            e.Graphics.DrawLine(Pens.Azure, 10, 10, 20, 20)
        End Sub
    
    End Class
    

    (Note also that in the above code, I am overriding the OnPaint method, rather than handling the corresponding Paint event. This is considered best practice for handling events in a derived class. But either way will work.)