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

设置Dock属性为非None后,调整用户控件大小绘图失效问题排查

问题原因与解决方案

我之前碰到过类似的问题,你的代码里主要有两个核心问题导致Dock属性变更后调整大小网格不显示:

1. 坐标计算错误,网格画到了控件可见区域之外

你的代码里用了this.Location.X和this.Location.Y作为网格线的起点,但控件的绘图坐标系是相对于自身客户区的——也就是说,控件自己的左上角永远是(0,0),和它在父容器里的位置(Location属性)无关。

当你设置Dock为非None的值(比如Fill、Top)时,控件的Location可能不再是(0,0),这就导致你画的网格线从父容器里的某个位置开始,完全超出了控件自己的可见区域。调整控件大小后,原来的绘制区域被擦除,新区域自然看不到网格。

2. 重绘逻辑没有在控件大小变化时触发

如果你的DrawGrid方法只在初始化时调用了一次,那么当控件大小改变时,系统不会自动重新调用它。你需要确保控件在大小变化时触发重绘,让网格跟着控件尺寸更新。


修正后的代码

第一步:修复坐标计算与资源释放

先修改DrawGrid方法,把坐标改成控件自身的(0,0)起点,同时用using语句自动释放GDI+资源(比手动Dispose更安全,避免异常时资源泄漏):

private void DrawGrid(Graphics g)
{
    // using语句会自动释放brush和pen资源
    using (var hatchBrush = new HatchBrush(HatchStyle.LargeGrid | HatchStyle.Percent50, Color.LightGray, Color.Transparent))
    using (var gridPen = new Pen(hatchBrush, 1))
    {
        // 绘制垂直网格线(从顶部到底部)
        for (int i = 0; i < this.Size.Width; i += 50)
        {
            g.DrawLine(gridPen, new Point(i, 0), new Point(i, this.Size.Height));
        }
        // 绘制水平网格线(从左到右)
        for (int i = 0; i < this.Size.Height; i += 50)
        {
            g.DrawLine(gridPen, new Point(0, i), new Point(this.Size.Width, i));
        }
    }
}

第二步:确保重绘时机正确

把绘图逻辑放到控件的OnPaint方法里(这是控件绘图的标准入口),同时重写OnResize方法,在控件大小变化时强制触发重绘:

protected override void OnPaint(PaintEventArgs e)
{
    // 先调用基类方法,保证背景正常绘制
    base.OnPaint(e);
    // 在背景之上绘制网格
    DrawGrid(e.Graphics);
}

protected override void OnResize(EventArgs e)
{
    base.OnResize(e);
    // 控件大小变化时,强制触发重绘
    this.Invalidate();
}

这样修改后,不管你设置什么Dock属性,调整控件大小的时候,网格都会跟着自动更新,不会出现被擦除后不重绘的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:31:27