如何清除DrawPie历史绘制图形?C# WinForms绘图问题
问题分析
你的代码有两个核心问题导致叠加和无效覆盖:
- 未清空画布:每次Timer Tick都在同一个Bitmap上追加绘制,旧的图形不会自动消失,导致叠加。
- 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覆盖的思路错误:
- DrawPie绘制的是扇形的轮廓(弧线+两条半径),不是填充整个扇形区域,所以无法覆盖之前的绿色轮廓。
- 即使是填充扇形,局部覆盖也会因为背景还有其他元素(如十字线、圆圈)而破坏画面,不如每次重新绘制整个画布更可靠。
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

