简体   繁体   English

VB.NET 在 PictureBox 上绘制多条线而不删除以前的更改

[英]VB.NET drawing multiple lines on a PictureBox without removing previous changes

I'm trying to draw multiple lines on a VB.NET PictureBox without deleting the previous changes.我试图在 VB.NET PictureBox上绘制多条线,而不删除以前的更改。 If I try to draw two lines on a PictureBox during different times with e.graphics , then it would delete previous lines/changes.如果我尝试在不同时间使用e.graphicsPictureBox上绘制两条线,那么它将删除以前的线/更改。

I'm using this code on a PictureBox 's paint event.我在PictureBoxpaint事件上使用此代码。

Public Class DrawLine

Dim point1X As Integer = 10
Dim point1Y As Integer = 10

Dim point2X As Integer = 50
Dim point2Y As Integer = 50

Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
    Dim pt As New Point(point1X, point1Y)
    Dim pt1 As New Point(point2X, point2Y)
    e.Graphics.DrawLine(Pens.Green, pt, pt1)    
End Sub

End Class

This example perfectly draws a green line inside the PictureBox .此示例完美地在PictureBox内绘制了一条绿线。

However, when I have a button that draws another line on the PictureBox after the form has already been painted, the previous line drawn disappears.但是,当我有一个按钮在窗体已经绘制后在PictureBox上绘制另一条线时,之前绘制的线消失了。

For example, if I have a function like this that draws another line例如,如果我有一个像这样画另一条线的 function

Private Function DrawAnotherLine(xPos1 As Integer, yPos1 As Integer, xPos2 As Integer, yPos2 As Integer)

point1X = xPos1
point1Y = yPos1

point2X = xPos2
point2Y = yPos2

PictureBox1.Invalidate()
End Function

It deletes the first line drawn and only draws the second line.它删除绘制的第一条线,只绘制第二条线。 I want it draw the second line on top of the first line and not just delete the first line though, how would I do this?我希望它在第一行之上绘制第二行,而不仅仅是删除第一行,我该怎么做?

(Note: I cannot include drawing the first line in the function, as this function will be used multiple times on top of the lines its already drawn). (注意:我不能包括在 function 中绘制第一行,因为此 function 将在其已绘制的行之上多次使用)。

GDI+ drawing is pretty simple: GDI+ 绘图非常简单:

  1. Declare one or more fields to store the data that represents your drawing.声明一个或多个字段来存储代表您的绘图的数据。
  2. Handle the Paint event of the control you want to draw on.处理要在其上绘制的控件的Paint事件。
  3. In the event handler in step 2, get the data from the field(s) declared in step 1 and perform the drawing.在步骤 2 的事件处理程序中,从步骤 1 中声明的字段中获取数据并执行绘图。
  4. To change the drawing, modify the field(s) declared in step 1 and call Invalidate on the control.要更改绘图,请修改在步骤 1 中声明的字段并在控件上调用Invalidate

If you want to be able to draw multiple lines then you first need a data structure that represents a single line and then somewhere to store multiple instances of that data structure.如果您希望能够绘制多条线,那么您首先需要一个表示单条线的数据结构,然后在某个地方存储该数据结构的多个实例。 The most obvious way to do that is to define a class or structure that contains the data for a single line, eg最明显的方法是定义一个 class 或包含单行数据的结构,例如

Public Class Line

    Public ReadOnly Property StartPoint As Point

    Public ReadOnly Property EndPoint As Point

    Public Sub New(startPoint As Point, endPoint As Point)
        Me.StartPoint = startPoint
        Me.EndPoint = endPoint
    End Sub

End Class

and to then declare a field that refers to a collection of that type:然后声明一个引用该类型集合的字段:

Private lines As New List(Of Line)

Your Paint event handler then draws all the lines in the collection:然后,您的Paint事件处理程序绘制集合中的所有线条:

Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
    For Each line In lines
        e.Graphics.DrawLine(Pens.Black, line.StartPoint, line.EndPoint)
    Next
End Sub

To draw a new line, you add a new Line object to the collection and Invalidate the control:要绘制一条新线,请向集合中添加一条新Line object 并使控件Invalidate

Private Sub AddNewLine(startPoint As Point, endPoint As Point)
    lines.Add(New Line(startPoint, endPoint))
    PictureBox1.Invalidate()
End Sub

How you get those points is up to you.如何获得这些分数取决于您。 You might record the location on a MouseDown event and then call AddNewLine on a MouseUp event or you might do something else entirely.您可以在MouseDown事件上记录位置,然后在MouseUp事件上调用AddNewLine ,或者您可以完全执行其他操作。

It is also preferable to specify the smallest area possible when calling Invalidate , but that's beyond the scope of this question.调用Invalidate时最好指定可能的最小区域,但这超出了此问题的 scope 范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM