【问题标题】:Applying style changes to individual cells in DataGridView is very slow将样式更改应用于 DataGridView 中的单个单元格非常慢
【发布时间】:2023-03-12 05:27:01
【问题描述】:

我有一个手动填充的 DataGridView (DGV)(未绑定到数据源)。它相对较小(12 列 x 62 行)。当我的表单加载时,它会使用来自不同来源的数据填充每个单元格,并将样式更改应用于某些单元格,例如前景色、背景色,以及可能的字体更改。

除了风格变化外,一切都很好。我使用秒表做了一些测试,格式化所用的时间大约是填充表单的所有处理时间的 2 倍。我的计算相当密集,而我认为应用格式几乎是瞬时的,所以我很困惑为什么应用一些样式更改所花费的时间是我密集计算的两倍。

我已经采取了一些措施来大大减少时间,例如在我的格式化开始之前为我的 DGV 开启 double-buffering 和 suspending drawing 并在之后恢复它。这些帮助很大,并且还消除了在我的 DGV 的每个单元被重新粉刷时发生的闪烁。据我所知,做这两件事有助于将风格变化的实际绘画结合到一个单一的绘画操作中。所以我的表单加载的大致轮廓是这样的:

  1. 开始加载表单
  2. DGV 的“SuspendDrawing”
  3. 用数据填充 DGV
  4. 对每个单元格应用样式更改
  5. DGV 的“ResumeDrawing”和刷新(重绘)DGV。

为了澄清,第 4 步仅由如下几行组成:

myCell.Style = New DataGridViewStyle()
myCell.Style.BackColor = ...
myCell.Style.ForeColor = ...
myCell.Style.Font = New Font()

在所有这些步骤中,第 4 步花费的时间最多。甚至第 5 步也几乎是瞬间完成的。这对我来说没有意义。进行第 4 步时绘图暂停,因此不应进行图形计算或绘图。它应该纯粹存储每个单元格的样式更改。

那么,为什么应用单元格样式更改如此缓慢,除了我已经拥有的之外,我还能做些什么来加快速度?

2020 年 2 月 5 日更新

我被要求提供可重现的代码。我需要一些时间来组装一个 MWE。同时,希望这会有所帮助:填充表格后(上面的第 3 步),我在第 4 步中应用单元格样式,如下所示:

For Each row As DataGridViewRow In myDGV.Rows
  For Each cell As DataGridViewCell In row.Cells
    Select Case [somecondition]
      Case X
        cell.Style = New DataGridViewStyle()
        cell.Style.BackColor = Colors.White
        cell.Style.ForeColor = Colors.Black
        cell.Style.Font = New Font(DefaultFont, FontStyle.Italic)
      Case Y
        [similar]
      Case ...
    End Select
  Next
Next

【问题讨论】:

  • 您需要给我们可重现的代码。
  • 在哪里 /什么时候应用这些属性?看来您没有使用CellFormatting、CellPainting 等事件......因此,每次更改单个属性时,您可能会生成大量格式化事件。您可以提供一个已配置的对象,而不是更改 live 单元格的每个属性...
  • 我编辑了更多细节。如果这还不够,我明天会组装一个 MWE。
  • 使用提供的事件来格式化/绘制 DGV 的单元格/行。
  • 按照建议,您应该处理适当的事件并按需配置每个单元。也就是说,如果您打算按照自己的方式进行操作,部分问题在于您首先设置单元格的Style 属性,然后设置该DataGridViewCellStyle 的三个属性。这意味着您正在修改一个活细胞四次。你应该做的是首先创建和配置DataGridViewCellStyle,然后设置单元格的Style。顺便说一句,这只是一个变化。始终考虑您执行与 UI 相关的操作的顺序。

标签: vb.net winforms performance datagridview


【解决方案1】:

我遵循 jmcilhinney 的建议,为每次迭代创建和配置了一个 Style 变量并将其分配给单元格,而不是多次修改每个活单元格的 Style。这使格式化速度提高了大约 140 倍,从 1.4 秒减少到 0.01 秒。我生成的代码如下所示:

For Each row As DataGridViewRow In myDGV.Rows
  For Each cell As DataGridViewCell In row.Cells
    Select Case [somecondition]
      Case X
        Dim styleVar as New DataGridViewStyle()
        styleVar.BackColor = Colors.White
        styleVar.ForeColor = Colors.Black
        styleVar.Font = New Font(DefaultFont, FontStyle.Italic)
        cell.Style = styleVar
      Case Y
        [similar]
      Case ...
    End Select
  Next
Next

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-15
    • 2011-07-03
    • 2012-08-04
    • 2011-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多