Gunnar Stableford
Gunnar Stableford

Reputation: 5

How to use the Paint event more than once on a form?

Okay, so I am trying to make a program that each time you click (doesn't matter where) a random colored, and sized circle appears where you happened to click. however, the only way I can add a shape is via Paint event. here is the code I have now:

Private Sub Form1_Paint(ByVal Sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint


    Using Brush1 As New SolidBrush(Color.Orange)
            e.Graphics.FillEllipse(Brush1, MousePosition.X, MousePosition.Y, 100, 100)
        End Using

End Sub

I need to know a line of code that I can use in a mouse click event, that will re-run this sub. I know how to change the size, and make it random, I just don't know how to run this sub multiple times, more precisely; run this sub once after each mouse click. If someone can help, I would appreciate it!

Upvotes: 0

Views: 2516

Answers (1)

xfx
xfx

Reputation: 1358

Just as Plutonix explained, a refresh is handled by calling the Invalidate method.

The thing you need to remember is that whatever is painted on a surface is not persistent, so you need to redraw the whole screen every time. There are, of course, many ways in which this can be optimized for performance purposes, as this process can be extremely CPU intensive; specially, since GDI+ is not hardware accelerated.

So, what you need to do is:

  1. Record every click (x, y position) and store it

  2. Since the radius of each circle is random, determine the radius when the user clicks the form, then store it along with the x, y position of the click

  3. Then, have the Paint event re-draw each stored sequence of clicks (with their respective radii) and re-draw each circle over and over.

Here's an implementation that will do the trick. Just paste this code inside any Form's class to test it:

Private Class Circle
    Public ReadOnly Property Center As Point
    Public ReadOnly Property Radius As Integer

    Public Sub New(center As Point, radius As Integer)
        Me.Center = center
        Me.Radius = radius
    End Sub
End Class

Private circles As New List(Of Circle)

Private radiusRandomizer As New Random()

Private Sub FormLoad(sender As Object, e As EventArgs) Handles MyBase.Load
    Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True) ' Not really necessary in this app...
    Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
    Me.SetStyle(ControlStyles.ResizeRedraw, True)
    Me.SetStyle(ControlStyles.UserPaint, True)
End Sub

Private Sub FormMouseClick(sender As Object, e As MouseEventArgs) Handles Me.MouseClick
    circles.Add(New Circle(New Point(e.X, e.Y), radiusRandomizer.Next(10, 100)))
    Me.Invalidate()
End Sub

Private Sub FormPaint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    Dim g As Graphics = e.Graphics

    g.Clear(Color.Black)

    Using p As New Pen(Color.White)
        For Each c In circles
            g.DrawEllipse(p, c.Center.X - c.Radius \ 2, c.Center.Y - c.Radius \ 2, c.Radius, c.Radius)
        Next
    End Using
End Sub

Here's what you'll get after a few clicks on the form enter image description here

Upvotes: 1

Related Questions