如何在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
相关产品推荐
相关产品推荐

