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

WinForm绘图:预期绘制单个椭圆却出现两个的问题求助

问题分析与解决方案

嘿,我来帮你搞清楚为什么有时候会画出两个圆形!

问题根源

你的代码里有两个关键问题导致了这个现象:

  • 每次Paint事件都新建Random实例:Random默认用当前系统时钟的滴答数作为种子。如果Paint事件在短时间内被多次触发(比如窗口调整大小、被其他窗口遮挡后恢复、最小化还原等),连续创建的Random会使用相同的种子,要么生成相同的坐标(看起来像同一个圆但其实重复绘制了),要么生成不同坐标导致出现两个圆。
  • Paint事件会被系统多次调用:系统会在需要重绘窗体内容时自动触发Paint事件,每次触发都会执行你的绘图代码,相当于每次都画一个新圆,自然会出现多个圆的情况。

解决方案

根据你的需求,我给你两种可行的修改方案:

方案1:每次重绘都生成新的随机圆(确保随机数不重复)

把Random实例提升为窗体类的私有字段,避免每次创建重复种子的实例,同时每次重绘前清除画布:

// 在窗体类里定义私有字段
private Random r = new Random();

private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    int leftX = 20;
    int topY = 60;
    int width = this.Width - (3 * leftX);
    int height = this.Height - (int)(2.5 * topY);
    
    // 生成随机坐标,确保圆完全在边界内
    float x = r.Next(leftX, width - 100);
    float y = r.Next(topY, height - 100);
    
    Rectangle rect = new Rectangle((int)x, (int)y, 100, 100);
    
    // 先清除画布,避免保留之前的圆
    g.Clear(this.BackColor);
    
    g.DrawRectangle(new Pen(Color.Black), rect); // 圆的外框
    g.DrawRectangle(new Pen(Color.Black, 3), leftX, topY, width, height); // 边界框
    g.FillEllipse(new SolidBrush(Color.Black), rect);
}

方案2:只生成一次随机位置,每次重绘都画同一个圆

如果你希望窗体上始终只有一个固定的随机圆,把坐标的生成移到窗体加载事件里:

private Random r = new Random();
private Rectangle circleRect;

private void Form1_Load(object sender, EventArgs e)
{
    int leftX = 20;
    int topY = 60;
    int width = this.Width - (3 * leftX);
    int height = this.Height - (int)(2.5 * topY);
    
    float x = r.Next(leftX, width - 100);
    float y = r.Next(topY, height - 100);
    circleRect = new Rectangle((int)x, (int)y, 100, 100);
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    int leftX = 20;
    int topY = 60;
    int width = this.Width - (3 * leftX);
    int height = this.Height - (int)(2.5 * topY);
    
    g.Clear(this.BackColor);
    
    g.DrawRectangle(new Pen(Color.Black), circleRect); // 圆的外框
    g.DrawRectangle(new Pen(Color.Black, 3), leftX, topY, width, height); // 边界框
    g.FillEllipse(new SolidBrush(Color.Black), circleRect);
}

额外提示

我还调整了你的随机坐标生成逻辑,原来的r.Next(20, width - 100)改成了r.Next(leftX, width - 100),这样能确保圆完全落在你定义的边界框内,不会超出范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:39:57