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

PictureBox自动绘制矩形失效:仅交互操作时可成功绘制

解决PictureBox自动绘制矩形不显示的问题

问题原因

你用CreateGraphics()创建的是控件的临时绘图上下文,当控件触发重绘(比如窗体初始化阶段的首次渲染、窗口被遮挡后恢复)时,系统会清空这个临时表面并重新绘制控件内容(也就是你设置的Image),所以构造函数和Shown事件里的绘制会被后续的重绘操作覆盖掉。而点击事件触发时,控件已经完成了初始重绘,临时绘制的内容不会立刻被擦掉,所以能看到,但这不是可靠的实现方式。

正确解决方案

方案1:利用PictureBox的Paint事件(推荐)

这是WinForms绘图的标准做法,所有需要持久显示的绘制逻辑都应该放在Paint事件里,每次控件重绘时都会自动执行这段代码。

步骤:

  • 定义存储矩形信息的集合(支持多矩形绘制)
  • 绑定PictureBox的Paint事件
  • 在Paint事件中使用事件提供的Graphics对象绘制矩形

修改后的代码:

namespace myGUI
{
    public partial class formPicture : Form
    {
        // 存储需要绘制的矩形集合
        private List<Rectangle> _rectangles = new List<Rectangle>();

        public formPicture()
        {
            InitializeComponent();
            pbImage.Image = Image.FromFile(@"../../Images/myImage.bmp");
            
            // 添加需要绘制的矩形
            _rectangles.Add(new Rectangle(500, 200, 20, 20));
            // 可继续添加更多矩形
            // _rectangles.Add(new Rectangle(100, 100, 30, 30));
            
            // 绑定Paint事件
            pbImage.Paint += PbImage_Paint;
        }

        private void PbImage_Paint(object sender, PaintEventArgs e)
        {
            // 使用Paint事件提供的Graphics对象,这是控件重绘的正式上下文
            using (var pen = new Pen(Color.Red, 5))
            {
                foreach (var rect in _rectangles)
                {
                    e.Graphics.DrawRectangle(pen, rect);
                }
            }
        }

        // 动态添加矩形的方法,调用后刷新控件
        private void AddRectangle(Rectangle rect)
        {
            _rectangles.Add(rect);
            pbImage.Invalidate(); // 触发重绘,显示新矩形
        }
    }
}

方案2:直接在Image对象上绘制(永久修改图片)

如果希望矩形直接嵌入图片本身,而非每次重绘时重新绘制,可以直接操作Image的绘图上下文。这种方式下,矩形会被保存到图片文件(若后续执行保存操作),修改后需刷新PictureBox显示。

示例代码:

namespace myGUI
{
    public partial class formPicture : Form
    {
        public formPicture()
        {
            InitializeComponent();
            
            // 加载图片并创建可编辑的Bitmap(Image.FromFile返回的对象为只读)
            using (var originalImage = Image.FromFile(@"../../Images/myImage.bmp"))
            {
                var editableBitmap = new Bitmap(originalImage);
                using (var g = Graphics.FromImage(editableBitmap))
                {
                    g.DrawRectangle(new Pen(Color.Red, 5), 500, 200, 20, 20);
                    // 可继续绘制更多矩形
                }
                pbImage.Image = editableBitmap;
            }
        }
    }
}

注意事项

  • 避免用CreateGraphics()做持久绘制,它仅适合临时、一次性的绘图需求(比如拖拽时的临时反馈)。
  • 使用画笔、画刷等GDI+对象时,用using语句自动释放资源,防止内存泄漏。
  • 方案1中,更新矩形列表后需调用pbImage.Invalidate()触发重绘。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 19:24:19