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

WinForm中使用Timer从底部垂直缩小矩形的实现问询

解决WinForm Timer实现矩形从底部向上缩小的问题

你现在的核心问题应该是没搞对矩形的坐标计算——要实现宽度不变、从底部向上缩减高度,关键是固定矩形的底部位置,通过调整顶部Y坐标来让高度逐步变小,而不是单纯改高度值却不调整位置。

先给你梳理下思路,再上修改后的代码:

关键逻辑说明

WinForm的坐标系是左上角为(0,0),Y轴向下递增。所以要让矩形从底部往上缩,我们需要:

  • 固定矩形的宽度和底部Y坐标(比如贴在窗体底部上方)
  • 每次Timer触发时,减小矩形的高度,同时把矩形的顶部Y坐标往上移(也就是Y值变大),这样底部位置不动,高度从下往上“收”

完整代码示例

1. 定义变量

先在窗体类里定义需要的参数:

// 矩形的固定宽度
private int _fixedRectWidth = 200;
// 矩形当前的高度(初始值设为你原来的195)
private int _currentRectHeight = 195;
// 矩形的底部Y坐标(固定不动)
private int _rectBottomY;
// 用于控制缩小的Timer
private Timer _shrinkTimer;

2. 初始化参数和Timer

在窗体的Load事件里初始化:

private void Form1_Load(object sender, EventArgs e)
{
    // 设置矩形底部位置:距离窗体底部50像素(可自行调整)
    _rectBottomY = this.ClientSize.Height - 50;
    
    // 初始化Timer
    _shrinkTimer = new Timer();
    _shrinkTimer.Interval = 50; // 每50毫秒缩一次,数值越小速度越快
    _shrinkTimer.Tick += ShrinkTimer_Tick;
    
    // 可以加个按钮来触发开始缩小,比如:
    // Button startBtn = new Button();
    // startBtn.Text = "开始缩小";
    // startBtn.Click += (s, args) => _shrinkTimer.Start();
    // this.Controls.Add(startBtn);
}

3. Timer Tick事件处理

这里负责更新高度并触发重绘:

private void ShrinkTimer_Tick(object sender, EventArgs e)
{
    // 当高度还大于0时继续缩小,避免负数
    if (_currentRectHeight > 0)
    {
        // 每次减少5像素高度,可调整步长
        _currentRectHeight -= 5;
        // 触发窗体重绘,会调用Paint事件
        this.Invalidate();
    }
    else
    {
        // 高度缩到0就停止Timer
        _shrinkTimer.Stop();
    }
}

4. 在Paint事件里绘制矩形

不要直接在Timer里用CreateGraphics,这种方式容易导致闪烁和资源泄漏,正确的做法是用窗体的Paint事件:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    
    // 计算矩形的顶部Y坐标:底部Y - 当前高度
    int rectTopY = _rectBottomY - _currentRectHeight;
    // 计算矩形的X坐标,让它在窗体中居中
    int rectX = (this.ClientSize.Width - _fixedRectWidth) / 2;
    
    // 创建矩形对象
    Rectangle targetRect = new Rectangle(rectX, rectTopY, _fixedRectWidth, _currentRectHeight);
    
    // 绘制矩形(这里用红色填充,你可以换成自己的样式)
    g.FillRectangle(Brushes.DarkRed, targetRect);
    // 也可以加个边框
    g.DrawRectangle(Pens.Black, targetRect);
}

为什么你之前的代码没成功?

你原来的代码可能只是单纯修改了size(高度)但没调整矩形的Y坐标,导致矩形是从顶部往下缩小,而不是底部往上。另外直接在Timer里创建Graphics对象没有及时释放,容易出问题,用Invalidate()触发Paint事件是WinForm绘制的标准做法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:53:05