【发布时间】:2025-12-31 11:50:07
【问题描述】:
使用 c++ Builder 2009 维护旧项目
在TListView 实例 (ViewStyle = vsReport) 中,设置为运行虚拟 (OwnerData = true) 我想尝试尽可能提高速度。每一点都有帮助。在OnData 事件中,我注意到Item->SubItems->Capacity = 0 一开始,随着子项目的添加,它每增加4。我在文档中读到 Capacity 是只读的,但我想尽可能避免 TStrings' 内部重新分配。由于我还需要进行缓存,我想我会使用TStringList 作为已经增长到所需容量的缓存。我假设 TStrings Assign() 然后会立即分配一个足够大的数组来存储所需数量的字符串?
Item->SubItems->Assign(Cache.SubItems) ;
虽然这行得通,但我注意到这会触发 ListView 再次调用 OnData,然后......导致它永远不会停止。
这样做很容易再次修复:
for (int x = 0 ; x < Cache.SubItems->Count ; x++)
Item->SubItems->Add(Cache.SubItems->Strings[x]) ;
当然,重点是能够从一开始就告诉SubItems 字符串的数量。
我意识到我可能遇到了旧的 VCL 问题?那早就解决了?还是我现在不明白这种行为有什么意义?
有没有办法“启用”Capacity 接受输入?以便为要添加的字符串分配足够的空间?
【问题讨论】:
-
我现在无权访问任何 C++ Builder,但是否有
BeginUpdate();和EndUpdate();可用于在更新时禁用触发事件?像obj->BeginUpdate(); ...; Item->SubItems->Assign(Cache.SubItems); ...; obj->EndUpdate();这样的东西。如果没有,也许将OnData事件处理程序存储在一个变量中,并在Assign()之前将其设置为NULL,然后在您更新后将其设置回来一切都可以工作。 -
优秀的建议 Ted,但它没有帮助,也许我需要重写我的问题,因为在
Assign()期间没有调用OnData。OnData像往常一样完成,为所有显示的对象调用它,但所有对象的序列随后再次开始,一次又一次。通常在没有活动时它会停止,现在它永远不会停止 -
进行更多测试时,似乎当我设置
Capacity时,值会保持不变(当我再次读出它时)。文档说没有,但我没有想到TListViewItemSubItems实现是一个继承自TStrings的类。 -
自从我在虚拟模式下使用
TListView已经有一段时间了,但我从来没有遇到过你所描述的问题。我有 CB2009 的 VCL 源代码,所以我明天会查看它并发布答案。但与此同时,CB2009 文档说TStrings::Capacity是读/写的,也许您将它与只读的TStrings::Count混淆了?TStrings::Assign()在内部调用(Begin|End)Update()。而 IIRC,TStrings::Assign()只是运行一个Add()循环。 -
@Peter 我现在已经添加了答案。
标签: c++builder vcl