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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 00:10:22