4

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
Victor Zakharov
  • 25,801
  • 18
  • 85
  • 151
N.T.C
  • 658
  • 2
  • 9
  • 20

5 Answers5

9

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.)

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
2

You should do this to draw your line

Public Class Form1
    Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
    Dim myPen As Pen

   'instantiate a new pen object using the color structure
    myPen = New Pen(Color=Color.Blue, Width=2)

   'draw the line on the form using the pen object
   e.Graphics.DrawLine(pen=myPen, x1=100, y1=150, x2=150, y2=100)

   End Sub       
End Class

or there is more simple solution is just add this code in the Form Paint Event

e.Graphics.DrawLine(Pens.Azure, 10, 10, 20, 20)
YellowFlash
  • 139
  • 8
1

You should put this code in the Paint event of the form, what's happening here is that the line is being drawn, but the form is re-painting as it finishes loading, so your line disappears. Also, try a black or more contrasting color, or you'll miss it against the window background color of the form.

kprobst
  • 16,165
  • 5
  • 32
  • 53
  • Having it inside OnPaint is better, because you control the order of paint events. If you use Paint event handler, you cannot guarantee the order of which your custom graphics is painted, especially with complex form inheritance, and event wiring. – Victor Zakharov Jul 27 '13 at 19:44
  • @Neolisk - Yes, I was thinking in terms of C# where it's called just `Paint`. Didn't remember the names were different :\ – kprobst Jul 28 '13 at 09:44
  • @kprobst - In c# it is also called OnPaint, because Neolisk was referring to the OnPaint override, not the Paint event. – Chris Dunaway Jul 29 '13 at 14:50
0

You can achieve this by adding a groupbox control to the form. Then remove the text (keep blank text), set the Height to 1 and select the BackColor you want.

Shamz
  • 1
  • although this answers the question per se, adding the actual code to do so would increase the quality of the answer. – Wim Ombelets May 13 '14 at 09:41
0

Draw multiple line

    Dim blackPen As New Pen(Color.Red, 3)
            Dim hwnd As IntPtr = PictureBox1.Handle
            Dim myGraphics As Graphics
            myGraphics = Graphics.FromHwnd(hwnd)
            Dim x1 As Integer = 100
            Dim x2 As Integer = 500
            Dim y1 As Integer = 10
            Dim y2 As Integer = y1
            Dim i As Int16 = 10, bothgap As Int16 = 20
            ' myGraphics.DrawLine(blackPen, x1, y1, x2, y2)
            For i = 1 To 10
                myGraphics.DrawLine(blackPen, x1, y1 + i * bothgap, x2, y1 + i * bothgap)
                'myGraphics.DrawLine(blackPen, x1, y1 + 2 * 20, x2, y1 + 2 * 20)
                'myGraphics.DrawLine(blackPen, x1, y1 + 3 * 20, x2, y1 + 3 * 20)
            Next
            x1 = 100
            x2 = 100
            y1 = 10 + bothgap
            y2 = 200 + bothgap / 2
            blackPen = New Pen(Color.Blue, 3)
            For i = 1 To 21
                '  myGraphics.DrawLine(blackPen, x1, y1, x2, y2)
                myGraphics.DrawLine(blackPen, x1 + (i - 1) * bothgap, y1, x2 + (i - 1) * bothgap, y2)
                '  myGraphics.DrawLine(blackPen, x1 + 2 * bothgap, y1, x2 + 2 * bothgap, y2)
            Next
    ```
Jay Weber
  • 64
  • 10
  • Welcome to SO. Please learn on [how to format your code](https://stackoverflow.com/help/formatting). Please also explain what you code do than just post the code. – hcheung Dec 20 '19 at 07:18