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

如何清除DrawPie历史绘制图形?C# WinForms绘图问题

问题分析

你的代码有两个核心问题导致叠加和无效覆盖:

  1. 未清空画布:每次Timer Tick都在同一个Bitmap上追加绘制,旧的图形不会自动消失,导致叠加。
  2. DrawPie参数错误:你传入的tx和ty是坐标值,但DrawPie需要的是起始角度和扫过角度(单位为度),这导致绘制的扇形完全不符合预期,后续的黑色覆盖自然也无效。
解决方案

我们需要每次Tick时清空整个画布,然后重新绘制所有元素,同时修正DrawPie的参数逻辑:

修改后的完整代码

using System;
using System.Drawing;
using System.Windows.Forms;

namespace My_DrawPie
{
    public partial class Form1 : Form
    {
        Timer t = new Timer();

        const int WIDTH = 300, HEIGHT = 300, HAND_RADIUS = 150;
        const int SECTOR_LIMIT = 20; // 扇形扫过的角度

        int currentAngle = 0; // 当前指针角度(度)
        int cx, cy; // 圆心坐标

        Bitmap bmp;
        Pen greenPen;
        Graphics g;

        public Form1()
        {
            InitializeComponent();
            // 提前创建Pen,避免每次Tick重复创建
            greenPen = new Pen(Color.Green, 1f);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 创建Bitmap
            bmp = new Bitmap(WIDTH + 1, HEIGHT + 1);

            // 窗口背景色
            this.BackColor = Color.Black;

            // 计算圆心
            cx = WIDTH / 2;
            cy = HEIGHT / 2;

            // 配置Timer
            t.Interval = 5;
            t.Tick += t_Tick;
            t.Start();
        }

        private void t_Tick(object sender, EventArgs e)
        {
            using (g = Graphics.FromImage(bmp))
            {
                // 1. 清空整个画布为黑色,清除所有旧绘制内容
                g.Clear(Color.Black);

                // 2. 绘制固定元素:外圈、内圈、十字线
                g.DrawEllipse(greenPen, 0, 0, WIDTH, HEIGHT); // 外圈
                g.DrawEllipse(greenPen, 80, 80, WIDTH - 160, HEIGHT - 160); // 内圈
                g.DrawLine(greenPen, new Point(cx, 0), new Point(cx, HEIGHT)); // 竖线
                g.DrawLine(greenPen, new Point(0, cy), new Point(WIDTH, cy)); // 横线

                // 3. 绘制扇形指针:起始角度为currentAngle - SECTOR_LIMIT,扫过SECTOR_LIMIT度
                // 注意:DrawPie的矩形是扇形外接矩形,这里调整矩形位置让扇形以圆心为中心
                int sectorSize = 100;
                Rectangle sectorRect = new Rectangle(cx - sectorSize/2, cy - sectorSize/2, sectorSize, sectorSize);
                g.DrawPie(greenPen, sectorRect, currentAngle - SECTOR_LIMIT, SECTOR_LIMIT);
            }

            // 更新PictureBox显示
            pictureBox1.Image = bmp;

            // 更新角度,循环360度
            currentAngle++;
            if (currentAngle >= 360)
            {
                currentAngle = 0;
            }
        }

        // 窗体关闭时释放资源
        protected override void OnFormClosed(FormClosedEventArgs e)
        {
            base.OnFormClosed(e);
            greenPen.Dispose();
            bmp.Dispose();
            t.Dispose();
        }
    }
}

关键修改点说明

  • 清空画布:每次Tick用g.Clear(Color.Black)清空整个Bitmap,确保旧图形被完全清除,避免叠加。
  • 修正DrawPie参数:
    • 扇形的外接矩形调整为以圆心(cx, cy)为中心,通过cx - sectorSize/2和cy - sectorSize/2设置矩形左上角坐标。
    • 第三个参数是起始角度,设为currentAngle - SECTOR_LIMIT,第四个参数是扫过角度,设为SECTOR_LIMIT,这样扇形会跟随currentAngle转动。
  • 资源优化:提前创建greenPen并在窗体关闭时释放,避免每次Tick创建新Pen造成资源浪费。
  • using语句管理Graphics:用using包裹Graphics.FromImage(bmp),确保Graphics自动释放,避免资源泄漏。

为什么黑色覆盖没用?

你之前用黑色DrawPie覆盖的思路错误:

  1. DrawPie绘制的是扇形的轮廓(弧线+两条半径),不是填充整个扇形区域,所以无法覆盖之前的绿色轮廓。
  2. 即使是填充扇形,局部覆盖也会因为背景还有其他元素(如十字线、圆圈)而破坏画面,不如每次重新绘制整个画布更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 16:35:24