Как использовать событие Paint более одного раза в форме?

Итак, я пытаюсь сделать программу, которая каждый раз, когда вы щелкаете (неважно, где), появляется кружок случайного цвета и размера там, где вы случайно щелкнули. однако единственный способ добавить фигуру — это событие 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

Мне нужно знать строку кода, которую я могу использовать в событии щелчка мыши, которое повторно запустит эту подпрограмму. Я знаю, как изменить размер и сделать его случайным, я просто не знаю, как запускать этот саб несколько раз, точнее; запускайте эту подпрограмму один раз после каждого щелчка мыши. Если кто-то может помочь, я был бы признателен!


person Gunnar Stableford    schedule 29.03.2016    source источник
comment
Событие рисования запускается довольно часто само по себе. заставить его, me.invalidate или me.refresh   -  person Ňɏssa Pøngjǣrdenlarp    schedule 29.03.2016
comment
Поскольку он каждый раз рисует одно и то же и будет сохраняться, кажется бессмысленным заставлять его перекрашивать.   -  person Ňɏssa Pøngjǣrdenlarp    schedule 29.03.2016
comment
Есть ли способ сделать то, что я пытаюсь сделать, без события рисования?   -  person Gunnar Stableford    schedule 30.03.2016
comment
Я понятия не имею, что вы пытаетесь сделать или почему вы не хотите использовать событие рисования для... рисования   -  person Ňɏssa Pøngjǣrdenlarp    schedule 30.03.2016


Ответы (1)


Как объяснил Plutonix, обновление обрабатывается вызовом метода Invalidate.

Вам нужно помнить, что все, что нарисовано на поверхности, не является постоянным, поэтому вам нужно каждый раз перерисовывать весь экран. Конечно, есть много способов оптимизировать это для повышения производительности, так как этот процесс может сильно нагружать ЦП; особенно, поскольку GDI+ не имеет аппаратного ускорения.

Итак, что вам нужно сделать, это:

  1. Записывайте каждый щелчок (положение x, y) и сохраняйте его.

  2. Поскольку радиус каждого круга является случайным, определите радиус, когда пользователь щелкнет форму, а затем сохраните его вместе с координатами x, y щелчка.

  3. Затем пусть событие Paint перерисовывает каждую сохраненную последовательность кликов (с соответствующими радиусами) и перерисовывает каждый круг снова и снова.

Вот реализация, которая поможет. Просто вставьте этот код в любой класс формы, чтобы протестировать его:

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

Вот что вы получите после нескольких кликов по форме введите здесь описание изображения

person xfx    schedule 30.03.2016
comment
Должны ли вы использовать Me.invalidate() или Me.refresh()? - person JackOfAll; 15.11.2020
comment
Me.Invalidate() предпочтительнее Me.Refresh(), поскольку он только запускает события OnPaint*, не заставляя перерисовывать какие-либо элементы пользовательского интерфейса. - person xfx; 22.11.2020
comment
Да, но зачем вам элементы управления пользовательского интерфейса для перерисовки? Им требуется перерисовка только в том случае, если форма перемещается, что выполняется автоматически. - person JackOfAll; 23.11.2020