ListView 控件加载非常缓慢

Posted

技术标签:

【中文标题】ListView 控件加载非常缓慢【英文标题】:ListView Control loads very slowly 【发布时间】:2009-03-03 00:27:13 【问题描述】:

当 ListView 有超过 15000 个包含 9 个子项的列表时,从查询中填充 ListView 的最快方法是什么。加载大约需要 6 分钟。

这是我为填充 ListView 控件而编写的内容。

Set rs = db.OpenRecordset(strSQL, dbOpenForwardOnly, dbReadOnly)

With Me.listViewData
    .View = lvwReport
    .GridLines = True
    .FullRowSelect = True
    .ListItems.Clear
    .ColumnHeaders.Clear
End With
'Set up column headers
With Me.listViewData.ColumnHeaders
    .Add , , "Client", 1440, lvwColumnLeft
    .Add , , "Contact", 2160, lvwColumnLeft
    .Add , , "Quote #", 720, lvwColumnCenter
    .Add , , "Date", 1140, lvwColumnLeft
    .Add , , "GrandTotal", 1440, lvwColumnRight
    .Add , , "Weighted Value", 1440, lvwColumnRight
    .Add , , "Chance %", 500, lvwColumnRight
    .Add , , "Sales Cycle", 1140, lvwColumnRight
    .Add , , "Won Orders", 1000, lvwColumnRight
    .Add , , "SalesRep", 1000, lvwColumnRight
End With

While Not rs.EOF
    Set lstItem = Me.listViewData.ListItems.Add()
    lstItem.Text = Nz(rs!Name, "")
    lstItem.SubItems(1) = Nz(rs!Company, "")
    lstItem.SubItems(2) = Nz(rs!QuoteNumber, "")
    lstItem.SubItems(3) = Nz(rs!OrderDate, "")
    lstItem.SubItems(4) = Nz(Format(rs!GrandTotal, "Currency"), "0.00")
    lstItem.SubItems(5) = Nz(Format(rs!GrandTotal * rs!Customfield1 / 100, "Currency"), "")
    lstItem.SubItems(6) = Nz(rs!Customfield1, "")
    lstItem.SubItems(7) = Nz(rs!Date1, "none")
    lstItem.SubItems(8) = Nz(rs!Detail, "")
    lstItem.SubItems(9) = Nz(rs!CustomT1, Nz(rs!UserID, ""))

    For I = 1 To Me.listViewData.ColumnHeaders.Count - 1
        Set sb = lstItem.ListSubItems(I)
        If rs!Customfield1 = 100 Or Not IsNull(rs!List) Then
            sb.ForeColor = vbBlue
            lstItem.ForeColor = vbBlue
        ElseIf rs!Cancelled = -1 Then
            sb.ForeColor = vbRed
            lstItem.ForeColor = vbRed
        Else
            sb.ForeColor = vbBlack
            lstItem.ForeColor = vbBlack
        End If
        DoEvents
    Next
    rs.MoveNext
Wend

【问题讨论】:

谢谢。我拿出了 DoEvents,它变得更快了。是否直接绑定到 MSAccess 2003 中的数据源? +1 清晰的演示文稿......看起来归功于各种响应者! 【参考方案1】:

你应该做的第一件事就是摆脱“doevents”,这是一个真正的性能杀手。

你必须动态加载列表视图吗?为什么不直接将其绑定到数据源?

【讨论】:

我拿出了 DoEvents,它变得更快了。如何在 MSAccess 2003 中直接绑定到数据源? 我不确定你是否问同样的问题。但我会问:你为什么要迭代更新列表框的每一行?我认为如果(在设计视图中)您选择列表框并将控制源/行源设置为必要的表或查询,性能会更好。【参考方案2】:

我能想到几件事:

虽然...Wend 是一种较慢的循环机制;使用 For...Next。 For...Next 更快——即使您必须运行另一个命令来获取 RecordCount。这是我使用的:

With rs
  If .RecordCount > 0 Then
    '-- MoveLast...MoveFirst will update the .RecordCount; depending on the type of DAO Recordset, RecordCount might only return "1" when there are more than that.
    .MoveLast
    .MoveFirst

    For lngCounter = 1 To .RecordCount
      '-- Code to add ListItems here

      .MoveNext
    Next lngCounter
  End If
  .Close
End With

使用 With...End With 来添加您的子项:

With Me.listViewData.ListItems.Add
  .Text = Nz(rs!Name, "")
  .SubItems(1) = Nz(rs!Company, "")
  .SubItems(2) = Nz(rs!QuoteNumber, "")
  .SubItems(3) = Nz(rs!OrderDate, "")
  .SubItems(4) = Nz(Format(rs!GrandTotal, "Currency"), "0.00")
  .SubItems(5) = Nz(Format(rs!GrandTotal * rs!Customfield1 / 100, "Currency"), "")
  .SubItems(6) = Nz(rs!Customfield1, "")
  .SubItems(7) = Nz(rs!Date1, "none")
  .SubItems(8) = Nz(rs!Detail, "")
  .SubItems(9) = Nz(rs!CustomT1, Nz(rs!UserID, ""))
End With

将填充器代码包装在:

DoCmd.Echo False

'-- Populate code

DoCmd.Echo True

希望有帮助!

【讨论】:

【参考方案3】:

检查 Listview 控件的方法,例如 beginupdate / endupdate 或将 refresh 设置为 false(如果可能)。这意味着在添加每个项目后,UI 不会尝试刷新屏幕,从而使添加速度更快。

Listview 控件的设计目的是容纳大量的项目,所以稍微挖掘一下就可以了。

【讨论】:

以上是关于ListView 控件加载非常缓慢的主要内容,如果未能解决你的问题,请参考以下文章

Nativescript-vue中的ListView滚动缓慢

使用 ListView 控件保存/加载 My.Settings - vb.net

如何清空android ListView控件的内容

Android-ListView-ArrayAdapter

VS 2008 (C#) 使用Winform方式,控件Listview要等数据全部加载完后才显示,有啥办法边加载边显示?

vb6加载时提示出错,窗体log文件中错误信息为:控件 XX 的类 MSComctlLib.ListView 不是一个已加载的控件类。