WinForms绘制新图形时已有图形消失的问题求助
问题修复方案
你的问题核心在于Paint事件没有绘制已保存的矩形列表,而且用CreateGraphics直接绘制的内容是临时的,窗口刷新就会消失。下面是修复后的完整代码,附带关键修改说明:
public partial class Form1 : Form { // 保存所有已完成绘制的矩形 List<Rectangle> _drawnRectangles = new(); // 拖拽时的起点和终点 Point _dragStart; Point _dragEnd; // 是否正在拖拽绘制 bool _isDragging = false; public Form1() { InitializeComponent(); } private void Form1_MouseDown(object sender, MouseEventArgs e) { _isDragging = true; _dragStart = e.Location; _dragEnd = e.Location; // 初始化终点,避免Paint时出错 } private void Form1_MouseMove(object sender, MouseEventArgs e) { if (_isDragging) { _dragEnd = e.Location; Refresh(); // 触发Paint事件更新画面 } } private void Form1_MouseUp(object sender, MouseEventArgs e) { if (_isDragging) { _isDragging = false; _dragEnd = e.Location; // 将完成的矩形添加到列表 _drawnRectangles.Add(CreateRectangle(_dragStart, _dragEnd)); Refresh(); // 触发Paint重绘所有内容 } } private void Form1_Paint(object sender, PaintEventArgs e) { // 先绘制所有已保存的矩形 foreach (var rect in _drawnRectangles) { e.Graphics.DrawRectangle(Pens.Black, rect); } // 如果正在拖拽,绘制临时的矩形预览 if (_isDragging) { var tempRect = CreateRectangle(_dragStart, _dragEnd); e.Graphics.DrawRectangle(Pens.Black, tempRect); } } // 提取矩形创建逻辑为独立方法,避免重复代码 private Rectangle CreateRectangle(Point start, Point end) { int x = Math.Min(start.X, end.X); int y = Math.Min(start.Y, end.Y); int width = Math.Abs(start.X - end.X); int height = Math.Abs(start.Y - end.Y); return new Rectangle(x, y, width, height); } }
关键修改点:
- 移除
CreateGraphics直接绘制:所有绘制逻辑统一放到Paint事件里,这是WinForm绘制的标准做法,确保窗口刷新时所有内容都会被重新绘制。 - 调整Paint事件逻辑:先绘制已保存的所有矩形,再绘制当前拖拽的临时矩形,这样拖拽时旧矩形不会消失。
- 清理冗余代码:把矩形创建逻辑提取为独立方法,移除不必要的成员变量,让代码更简洁。
- 简化MouseUp事件:只需要把完成的矩形添加到列表,调用
Refresh()触发Paint事件即可,不需要手动循环绘制。
这样修改后,拖拽绘制新矩形时,已有的矩形会一直显示,松开鼠标后新矩形会被保存并永久显示。
内容的提问来源于stack exchange,提问作者Jeremy
相关产品推荐
相关产品推荐

