What is seemingly a simple endeavour in this case actually turns out to be easier with a few bits of background knowledge.
The Form1.Paint
event is raised whenever the form is deemed to need a re-paint, for example if it has been covered by another form. For this exercise, you may not be concerned with more dots appearing than your code at first appears to produce. I shall not address that issue here.
The e.Graphics
object is not what you want if you want to persist the graphics, instead you want to use the object obtained from Control.CreateGraphics
.
It is recommended to use the .NET framework Random class instead of VB's Rnd()
.
Some classes use resources which need to be specifically disposed of, and so they have a .Dispose()
method. Graphics objects tend to be like that (also database and file operations). You can use a Using block to take care of calling Dispose for you.
And a very important point:
- Use Option Strict On. It will help you write code that works by pointing out any errors it can detect. Set it as the default for new projects.
A couple more things I should mention are that you should take some care when naming variables, and that it makes debugging easier to separate some things out into their own variables rather than writing one long line of code.
For things like timers, where you could drag a timer onto the drawing surface, I find it better to create it in code. That way you do not have to swap back and forth between the designer and code windows to change parameters, and you don't wonder where something like "Timer1" came from.
After all that, I came up with the (not necessarily very good) code:
Option Infer On
Option Strict On
Public Class Form1
Dim rand As New Random
Dim tim As Timer
Sub DrawDots(sender As Object)
' This sub could have been called with anything as sender, so check that
' it is actually a Control
Dim self As Control = TryCast(sender, Control)
If self Is Nothing Then
Exit Sub
End If
Using g = self.CreateGraphics()
Dim nDots = rand.Next(1, 26)
Dim circleRadius = 20
For i = 1 To nDots
Dim xLoc = rand.Next(0, 420)
Dim yLoc = rand.Next(0, 420)
Dim col = Color.FromArgb(rand.Next(0, 256), rand.Next(0, 256), rand.Next(0, 256))
Using br As New SolidBrush(col)
g.FillEllipse(br, xLoc, yLoc, circleRadius, circleRadius)
End Using
Next
End Using
End Sub
Sub DrawDotsOnTimerTick(sender As Object, e As EventArgs)
DrawDots(Me)
End Sub
Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
DrawDots(sender)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
DrawDots(Me)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
tim = New Timer
tim.Interval = 2000
AddHandler tim.Tick, AddressOf DrawDotsOnTimerTick
tim.Start()
End Sub
End Class