如何在窗体上多次使用 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+ 不是硬件加速的。
所以,您需要做的是:
记录每次点击(x,y位置)并存储
由于每个圆的半径是随机的,当用户点击表单时确定半径,然后将其与点击的x,y位置一起存储
然后,让 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
以下是您在表单上点击几下后会得到的结果
好的,所以我正在尝试制作一个程序,每次您单击(无论在何处)时,都会在您碰巧单击的位置出现一个随机颜色和大小的圆圈。但是,我可以添加形状的唯一方法是通过 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+ 不是硬件加速的。
所以,您需要做的是:
记录每次点击(x,y位置)并存储
由于每个圆的半径是随机的,当用户点击表单时确定半径,然后将其与点击的x,y位置一起存储
然后,让
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
以下是您在表单上点击几下后会得到的结果