我在表单上有一个垂直和水平可滚动的DataGridView。
我使用虚拟模式,因为底层数据表很大。
当我向右滚动时,如果视图中没有完整显示最后一列,那么我会看到对CellValueNeeded的重复调用。
我该如何解决这个问题?
我的想法:
为什么CellValueNeed会被反复调用部分可见的列?也许我可以解决这个原因。
在CelValueNeeded中 - 我可以检测到它是否部分可见并且无需处理即可返回?当我检查单元格值时,“显示”和“可见”都是正确的。
我的代码:
private void grid_Data_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
{
Console.WriteLine("CellValue: " + e.RowIndex + " " + e.ColumnIndex);
if (e.RowIndex > Grid.Rows.Count - 1)
return;
DataGridView gridView = sender as DataGridView;
e.Value = Grid.Rows[e.RowIndex][e.ColumnIndex];
gridView.Rows[e.RowIndex].HeaderCell.Value = (e.RowIndex).ToString();
}
EDIT1:
在Digitalsa1nt的回答之后,我找到了解决问题的方法。它很复杂,因为第一列的处理方式与最后一列不同。如果你要设置RowHeaders,它会有所不同。
在上面的CellValueNeed中,如果以下函数为真,我现在返回。
private bool IsPartiallyVisible(DataGridView gridView, DataGridViewCellValueEventArgs e)
{
if (gridView.FirstDisplayedScrollingColumnIndex == e.ColumnIndex)
{
if (gridView.FirstDisplayedScrollingColumnHiddenWidth != 0)
{
return true;
}
}
bool sameWidth = gridView.GetColumnDisplayRectangle(e.ColumnIndex, false).Width == gridView.GetColumnDisplayRectangle(e.ColumnIndex, true).Width;
return !sameWidth;
}
答案 0 :(得分:3)
查看CellValueNeeded
的{{3}},它就像是一个标准的视觉事件一样,只要一个细胞成为"可见",我就不会&# 39;认为它定义了用于理解视觉偏好的逻辑。看起来好像它试图让细胞充分准备好进入视野"。我怀疑任何中间状态都没有曝光。
那说有一些建议MSDN documentation(SO回复)和here(奇怪的网络博客)提到使用DataGridView.GetColumnDisplayRectangle
以确定是否有矩形单元格在屏幕的范围内。
以下是网络博客的摘录:
调用GetColumnDisplayRectangle的第二个参数 CutOverFlow,这是一个控制是否为的布尔值 函数返回完整的列矩形(即使列是 不完全可见)或只是列的矩形部分 这是可见的。
通过调用此方法两次,将CutOverFlow设置为true并执行一次 一旦将其设置为false,您就可以创建一个比较它的函数 结果并在列仅部分时返回布尔值 可见:
返回dg.GetColumnDisplayRectangle(columnindex,False).Width = _
dg.GetColumnDisplayRectangle(columnindex,True).Width
这将允许您在调用grid_Data_CellValueNeeded
时停止处理,并且上述内容根据最后一个单元格位置返回false。