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
VS 2008 (C#) 使用Winform方式,控件Listview要等数据全部加载完后才显示,有啥办法边加载边显示?
vb6加载时提示出错,窗体log文件中错误信息为:控件 XX 的类 MSComctlLib.ListView 不是一个已加载的控件类。