我已在表单上实现了 DataGridView
并成功实现了 VirtualMode
。这会从本地缓存检索单元格数据,并且在填充网格/分页等时,所有内容似乎都能正常工作。我处理 DataGridView.CellValueNeeded
事件来填充单元格。
在 DataGridView 上,我将 AutoSizeColumnsMode
属性设置为 DataGridViewAutoSizeColumnsMode.DisplayedCells
。我注意到,在使用 VirtualMode 时,填充单元格后,DataGridView 似乎不尊重 AutoSizeColumnsMode。我已经检查过this article但没有找到解决方案。
我最终想做的是不依赖 AutoSizeColumnsMode
属性,而是在某处调用 .AutoResizeColumn()
方法调整大小,因此我最初自动调整列大小,但随后允许用户调整大小。
我尝试了以下方法,但效果有限或没有成功:
将
DataGridView.AutoSizeColumnsMode
设置为.None
。然后在我的.CellValueNeeded
处理程序private void dataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) { // ... Get cell value from cache dataGridView.AutoResizeColumn(e.ColumnIndex, DataGridViewAutoSizeColumnMode.DisplayedCells); }
这会抛出一个
StackOverFlowException
大概是因为它 反复引发.CellValueNeeded
。尝试了完全相同的操作,除了
.CellFormatting
事件处理程序。得到相同的StackOverFlowException
。尝试使用和不使用
DataGridView.SuspendLayout/ResumeLayout
:private void dataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) { // ... Get cell value from cache dataGridView.CellValueNeeded -= dataGridView_CellValueNeeded; dataGridView.AutoResizeColumn(e.ColumnIndex, DataGridViewAutoSizeColumnMode.DisplayedCells); dataGridView.CellValueNeeded += dataGridView_CellValueNeeded; }
这会给出所有空白单元格,因此没有用。
这个实际上有点作用,但我不明白的原因:
private void dataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e) { // ... Get cell value from cache dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells; }
它正确地调整了列的大小,但必须对所需的每个单元格值重复调用它似乎很奇怪。另外,我不能立即将其设置为 .None,否则它会再次
StackOverFlowException
。因此,我不能允许用户调整列的大小。如文章中所述,从我的
.CellValueNeeded
处理程序调用.UpdateCellValue()
也会引发StackOverFlowException
。
那么是否有可能在某个地方调用 .AutoResizeColumn()
,而在它溢出之前不会引发 .CellValueNeeded
?由于 #4 似乎能够执行自动调整大小功能,似乎我也可以从某个地方手动调用它。
最佳答案
我认为这可能是解决方案,尽管我仍然有兴趣听听其他人的意见。
我继续查看 DataGridView
引发的一些其他事件,并找到了 .RowPostPaint
事件。我创建了以下处理程序:
private void dataGridView_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
if (dataGridView.AllowUserToResizeColumns) //So not to run unnecessarily
{
return;
}
var lastIndex = dataGridView.Rows.GetLastRow(DataGridViewElementStates.Displayed);
if (e.RowIndex == lastIndex) //Only do on the last displayed row
{
dataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells);
dataGridView.AllowUserToResizeColumns = true; // User has control from here on
}
}
这会在初始数据加载时完成列的自动调整大小,然后允许用户从那里重新调整大小。它只执行一次,因此比所需的每个单元格值要好得多。我必须在初始数据加载之前设置 dataGridView.AllowUserToResizeColumns = false
。
这似乎符合要求。用户将在初始加载时看到非常适合的列,并可以从那里进行调整,并且我的大多数数据从行到行的长度相当,因此在大多数情况下不应截断或浪费空间。
关于c# - Winforms DataGridView在VirtualMode什么时候调用AutoResizeColumn?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9553022/