You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET实现鼠标移动在图片上划线时前一条线消失问题求助

问题根源

你当前的代码仅存储了单条正在绘制的线段的起点st和终点en,每次调用PictureBox1.Invalidate()触发控件重绘时,Paint事件只会绘制最新的这一条线段,此前绘制的内容没有被持久化存储,因此会被清空。


方案1:存储所有历史线段,重绘时全部绘制

该方案灵活度高,后续如果需要支持删除、修改已有线段的需求可以直接扩展。

修改步骤:

  1. 新增线段存储结构和全局存储列表
  2. 鼠标抬起时将绘制完成的线段存入列表
  3. Paint事件中遍历所有历史线段逐一绘制

完整修改后代码:

Dim st, en As New Point
Dim p As Pen
Private mouseButtonPressed As Boolean = False
' 新增线段结构
Public Structure DrawLine
    Public StartPoint As Point
    Public EndPoint As Point
    Sub New(s As Point, e As Point)
        StartPoint = s
        EndPoint = e
    End Sub
End Structure
' 存储所有已完成绘制的线段
Dim lineList As New List(Of DrawLine)

Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
    p = New Pen(Color.Black, 2)
    Dim g As Graphics = e.Graphics
    ' 先绘制所有历史线段
    For Each l In lineList
        g.DrawLine(p, l.StartPoint, l.EndPoint)
    Next
    ' 再绘制当前正在拖动的线段(预览效果)
    If mouseButtonPressed Then
        g.DrawLine(p, st, en)
    End If
End Sub

Private Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
    mouseButtonPressed = False
    ' 绘制完成,将当前线段加入历史列表
    lineList.Add(New DrawLine(st, en))
End Sub

Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
    If mouseButtonPressed Then
        en = e.Location
        PictureBox1.Invalidate()
    End If
End Sub

Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
    If e.Button = MouseButtons.Left Then
        st = New Point(e.X, e.Y)
        mouseButtonPressed = True
    End If
End Sub

方案2:直接绘制到PictureBox的Image对象

该方案性能更优,适合不需要二次编辑已画线条的场景,绘制完成的内容会直接固化到图片上,不需要每次重绘所有历史线条。

修改步骤:

  1. 初始化时为PictureBox绑定一个和控件尺寸一致的空白Bitmap作为绘制载体
  2. 鼠标抬起时将完成的线段直接绘制到Bitmap上
  3. Paint事件仅需要绘制当前正在拖动的预览线段即可

完整修改后代码:

Dim st, en As New Point
Dim p As Pen
Private mouseButtonPressed As Boolean = False
' 初始化绑定绘制用的Bitmap
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim bmp As New Bitmap(PictureBox1.Width, PictureBox1.Height)
    Using g As Graphics = Graphics.FromImage(bmp)
        g.Clear(Color.White) ' 可替换为你需要的背景色
    End Using
    PictureBox1.Image = bmp
End Sub

Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
    p = New Pen(Color.Black, 2)
    ' 仅绘制当前拖动的预览线段
    If mouseButtonPressed Then
        e.Graphics.DrawLine(p, st, en)
    End If
End Sub

Private Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
    mouseButtonPressed = False
    ' 将完成的线段直接绘制到Image上固化
    Using g As Graphics = Graphics.FromImage(PictureBox1.Image)
        g.DrawLine(New Pen(Color.Black, 2), st, en)
    End Using
    PictureBox1.Invalidate()
End Sub

Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
    If mouseButtonPressed Then
        en = e.Location
        PictureBox1.Invalidate()
    End If
End Sub

Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
    If e.Button = MouseButtons.Left Then
        st = New Point(e.X, e.Y)
        mouseButtonPressed = True
    End If
End Sub

内容的提问来源于stack exchange,提问作者user17485293

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 03:24:03