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

如何在C#自定义DataGridView构造函数中强制计算RowHeadersWidth?

问题:如何在构造函数中强制计算DataGridView的RowHeadersWidth?

我自定义了继承自DataGridView的CustomGridView,设置了行标题自动宽度模式:RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders;
发现RowHeadersWidth的最终值不会在构造函数阶段计算完成,而是要等到控件加载前后才确定。我的应用需要根据控件尺寸将自定义控件并排排列,但在构造函数里没法完成正确排列,只能在控件加载后操作。

  • 构造函数中排列控件的结果:控件排列重叠,行标题宽度未正确计算
  • 加载事件后重新排列的结果:控件正常并排,行标题宽度符合预期

请问能否通过编程方式在构造函数中强制计算RowHeadersWidth?

CustomGridView代码

class CustomGridView : DataGridView
{
    public CustomGridView()
    {
        RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders;
        this.RowHeadersWidthChanged += CustomGridView_RowHeadersWidthChanged;
        ScrollBars = ScrollBars.None;
        InitGridView(3);
    }

    public void InitGridView(int numRows)
    {
        this.ColumnCount = 1;
        this.RowCount = numRows;
        for (int row = 0; row < numRows; row++) {
            Rows[row].HeaderCell.Value = "R" + (row+10).ToString();
            Rows[row].Cells[0] = new DataGridViewTextBoxCell();
        }

        Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
        this.Height = this.RowCount * this.RowTemplate.Height + 4;
        this.Width = RowHeadersWidth + 45;
        // 遗憾的是,构造函数中此处的RowHeadersWidth尚未得到最终值
    }

    private void CustomGridView_RowHeadersWidthChanged(object sender, EventArgs e)
    {
        // RowHeadersWidth在稍后(控件加载前后)更新
        this.Width = RowHeadersWidth + 45;
    }
}

主窗体代码

public partial class Form1 : Form
{
    private List<CustomGridView> cGridViews = new List<CustomGridView>();
    private int gvWidth1;
    private int gvWidth2;

    private Point GridViewLocation;

    public Form1()
    {
        InitializeComponent();
        GridViewLocation = new Point(10, 10);
        AddCustomGrid(new CustomGridView());
        AddCustomGrid(new CustomGridView());
        gvWidth1 = cGridViews[0].Width;
        this.Load += Form1_Load;
    }

    private void AddCustomGrid (CustomGridView cGridView)
    {
        cGridView.Location = GridViewLocation;
        this.Controls.Add(cGridView);
        cGridViews.Add(cGridView);
        GridViewLocation.X += cGridView.Width + 5;
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        // CustomGridView现在拥有正确的尺寸
        gvWidth2 = cGridViews[0].Width;
    }
}

解决方案:强制触发行标题宽度计算

在构造函数完成数据初始化后,通过调用PerformLayout()和AutoResizeRowHeadersWidth()方法,可直接强制计算行标题宽度,修改InitGridView方法如下:

public void InitGridView(int numRows)
{
    this.ColumnCount = 1;
    this.RowCount = numRows;
    for (int row = 0; row < numRows; row++) {
        Rows[row].HeaderCell.Value = "R" + (row+10).ToString();
        Rows[row].Cells[0] = new DataGridViewTextBoxCell();
    }

    Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    this.Height = this.RowCount * this.RowTemplate.Height + 4;
    
    // 强制完成布局并计算行标题宽度
    this.PerformLayout();
    this.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders);
    
    this.Width = RowHeadersWidth + 45;
}

说明

  • PerformLayout():强制控件完成当前布局逻辑,确保行标题单元格等子元素已初始化完毕,为宽度计算提供基础。
  • AutoResizeRowHeadersWidth():指定模式直接计算行标题宽度,无需依赖控件加载时的自动触发逻辑。
  • 修改后,构造函数中即可获取正确的RowHeadersWidth值,控件排列可一次到位,无需等到Load事件后调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:45:14