WinForms .NET 4.8自定义PictureBox触发Paint事件无限循环问题求解
问题根源
无限循环的核心触发原因是:你在PictureBoxEx1_Paint绘制事件的处理逻辑中,直接修改了PictureBoxEx1.Image属性。修改PictureBox的Image属性会自动触发控件重绘,进而再次调用Paint事件,形成无限递归循环。
解决方法
1. 修正Paint事件逻辑(核心修改)
完全删除Paint事件中修改Image属性的代码,两种模式都直接通过当前Paint事件的e.Graphics对象绘制内容即可:
Private Sub PictureBoxEx1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBoxEx1.Paint If LoadedImage Is Nothing Then Return End If If RadioButton_verschieben.Checked Then ' 移动缩放模式:绘制调整后的图片 Dim the_rectangle_to_be_zoomed_in_and_drawn As RectangleF = calculate_zoomed_and_or_moved_rect() e.Graphics.DrawImage(LoadedImage, the_rectangle_to_be_zoomed_in_and_drawn) ElseIf RadioButton_freihand.Checked Then ' 手绘模式:先绘制原图,再叠加绘制用户笔迹即可,无需修改Image属性 e.Graphics.DrawImage(LoadedImage, New RectangleF(PointF.Empty, PictureBoxEx1.Size)) FunctionsToDraw.DrawTheUsersPath(e.Graphics) End If End Sub
2. 额外优化建议
- 不要在绘制逻辑中调用
GC.Collect(),强制垃圾回收会严重拖慢绘制性能,该操作完全没有必要放在Paint事件中执行。 - 如果需要在单选按钮切换模式时刷新显示,只需要在RadioButton的
CheckedChanged事件中调用PictureBoxEx1.Invalidate()触发一次重绘即可,不需要修改Image属性。 - 注意
calculate_zoomed_and_or_moved_rect方法中的坐标逻辑:Paint事件的Graphics坐标是相对于PictureBox控件本身的,如果你当前返回的RectangleF用了相对于窗体的坐标,需要减去PictureBox自身的Location偏移,避免绘制错位。
3. 后续保存带笔迹图片的处理
如果后续需要将用户绘制的笔迹和原图合并保存,只需要在保存时新建一个Bitmap,把原图和笔迹统一绘制到这个Bitmap上再保存即可,运行过程不需要修改PictureBox的Image属性。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

