如何在窗体上多次使用 Paint 事件?

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

好的,所以我正在尝试制作一个程序,每次您单击(无论在何处)时,都会在您碰巧单击的位置出现一个随机颜色和大小的圆圈。但是,我可以添加形状的唯一方法是通过 Paint 事件。这是我现在的代码:

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

我需要知道可以在鼠标单击事件中使用的一行代码,它将重新 运行 这个子程序。我知道如何更改大小并使其随机,我只是不知道如何 运行 这个子多次,更准确地说; 运行 每次单击鼠标后此子一次。如果有人能提供帮助,我将不胜感激!

正如 Plutonix 所解释的,刷新是通过调用 Invalidate 方法来处理的。

你需要记住的是,在表面上绘制的任何东西都不是持久的,所以你每次都需要重新绘制整个屏幕。当然,有许多方法可以出于性能目的对其进行优化,因为此过程可能非常 CPU 密集;特别是,因为 GDI+ 不是硬件加速的。

所以,您需要做的是:

  1. 记录每次点击(x,y位置)并存储

  2. 由于每个圆的半径是随机的,当用户点击表单时确定半径,然后将其与点击的x,y位置一起存储

  3. 然后,让 Paint 事件重新绘制每个存储的点击序列(及其各自的半径)并一遍又一遍地重新绘制每个圆圈。

这是一个可以解决问题的实现。只需将此代码粘贴到任何表单的 class 中即可对其进行测试:

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

以下是您在表单上点击几下后会得到的结果