【问题标题】:Repeated calls to CellValueNeeded重复调用 CellValueNeeded
【发布时间】:2018-06-20 21:45:52
【问题描述】:

我在表单上有一个可垂直和水平滚动的 DataGridView。

我使用虚拟模式是因为底层数据表很大。

当我向右滚动时,如果最后一列没有完全显示在视图中,那么我会看到对 CellValueNeeded 的重复调用。

我该如何解决这个问题?

我的想法:

  1. 为什么仍会为部分可见的列重复调用 CellValueNeed?也许我可以解决这个问题。

  2. 在 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();
}

编辑1:

在 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;
    }

【问题讨论】:

  • 很高兴这个答案很有用。有时复杂是唯一的方法,但这种计算的处理时间应该相当短,我会留意内存使用情况以防万一,但你应该没问题。
  • CellValueNeeded 默认不这样做真的很奇怪。不过谢谢你的提示。
  • 我同意,我记得读过一篇讨论通用 Windows 平台应用程序中的可视化分层的文章,它讨论了这种情况。这不是一个完美的解释,但他们有一些理由允许在像你这样的情况下调用它,但对于我的生活,我不记得了。

标签: c# datagridview


【解决方案1】:

查看MSDN documentationCellValueNeeded 看起来好像这是一个标准的视觉事件,只要单元格变得“可见”就会触发,我认为它没有定义它用来理解视觉偏向性的逻辑.似乎它试图为细胞完全“在视野中”做准备。我怀疑没有暴露任何中间状态。

也就是说有一些建议here(SO 回复)和here(奇怪的网络博客)提到使用DataGridView.GetColumnDisplayRectangle 的目的是确定单元格的矩形是否在屏幕。

这是来自网络博客的 sn-p:

调用GetColumnDisplayRectangle的第二个参数 CutOverFlow,它是一个布尔值,用于控制是否 函数返回完整的列矩形(即使列是 不完全可见)或仅列矩形的一部分 这是可见的。

通过调用此方法两次,一次将 CutOverFlow 设置为 true,然后 一旦将其设置为 false,您就可以创建一个函数来比较 结果并在列仅部分显示时返回布尔值 可见:

返回 dg.GetColumnDisplayRectangle(columnindex, False).Width = _
dg.GetColumnDisplayRectangle(columnindex, True).Width

这将允许您在调用 grid_Data_CellValueNeeded 时停止处理,并且上面基于最后一个单元格位置返回 false。

【讨论】:

    猜你喜欢
    • 2014-09-14
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 2018-11-07
    • 2013-03-12
    • 2019-09-17
    • 2011-07-05
    • 2011-02-05
    相关资源
    最近更新 更多