可以快速打开并装有大量物品的组合盒
我有一个源自 DevExpress 的 TdxfCustomComboBox 的自定义组合框。在大多数情况下它工作得非常好......然后我收到了客户的报告,当他们尝试打开它时,弹出窗口需要 3 秒才能出现。经过一番调查后,我发现这是因为他们的数据库有大约 12000 个项目试图填充,并且每次都会重新创建弹出窗口并填充它。
这意味着包含此行的 StdCtrls.TListBoxStrings.Add
被调用 12000 多次,每个字符串一次。
SendMessage(ListBox.Handle, LB_ADDSTRING, 0, Longint(PChar(S)));
处理这一行需要多次遍历多层消息处理程序,这确实会让事情陷入困境。我觉得这种做法很愚蠢,因为实际上弹出窗口中实际上一次只显示了大约十几个项目。有谁知道不需要这种预加载并且可以扩展的组合框控件?
编辑:不幸的是,这里不能选择不加载 12,000 个项目。组合框中的项目数基于数据库中的项目数,并且它们都必须可用。也不是把它变成组合框以外的东西。没有足够的屏幕空间。
I've got a custom combo box descended from DevExpress's TdxfCustomComboBox. It works really well in most cases... and then I got a report from a client that when they try to open it it takes 3 seconds for the popup to appear. After a bit of investigation, I found out that that's because their database has about 12000 items that it's trying to populate, and it recreates the popup window and populates it each time.
This means that StdCtrls.TListBoxStrings.Add
, which contains this line, gets called 12000+ times, once for each string.
SendMessage(ListBox.Handle, LB_ADDSTRING, 0, Longint(PChar(S)));
Processing this line requires several trips through multiple layers of message handlers and really bogs things down. I find this kind of silly since only about a dozen or so items are actually displayed in the popup window at once anyway. Does anyone know of a combo box control that doesn't require this sort of pre-loading and can scale?
EDIT: Unfortunately, making it not load 12,000 items is not an option here. The number of items in the combo box is based on the number of items in the database, and they all have to be available. Neither is making it into something other than a combo box. Not enough screen real estate for that.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我能想到的最好的解决方案是使用 TButtonEdit,当您单击按钮时,将弹出一个包含项目的 TVirtualStringTree(速度快如闪电),每当用户单击某个项目时,弹出窗口将关闭,所选项目将被显示在 TButtonEdit 的文本属性中——这可以在几分钟内完成(5-10)
the best solution that I can think of is using a TButtonEdit and when you click on the button a TVirtualStringTree(which is lightning fast) will popup containing the items, whenever the user clicks on a item the popup will close and the selected item will be displayed in the TButtonEdit's text property -- this can be achieved in a matter of minutes(5-10)
另一种可能性:您可以在启动时创建组合框并保留它,当您在此表单上需要它时重新调整它的父级吗?
如果失败,您可以将字符串加载到另一个字符串列表中,并根据需要分配给组合框吗? (我不熟悉 TListBoxStrings。)
Another possibility: can you create the combo box at start-up and keep it around, reparenting it when you need it on this form?
Failing that, could you load the strings into another string list and .Assign to the combo box as necessary? (I'm not familiar with TListBoxStrings.)
一些选项。
1./ 您真的需要填充 12,000 个项目吗?您可以使用某种过滤方案并仅返回该数据的子集吗?
2./ 必须使用组合框吗?您是否有足够的屏幕空间来使用虚拟列表视图? (自己处理存储和分页)
3./ 创建您自己的虚拟组合框...在虚拟列表视图上对虚拟化技术进行建模。
4./作弊...而不是组合框,而是使用带有“浏览”按钮的编辑框,该按钮打开一个可以动态填充的列表。
据我所知,没有任何模式可以让您使用 dev Express(或本机)组合框来执行此操作。
Some options.
1./ Do you really have to populate with 12,000 items? can you use some filtering scheme and only return a subset of that data?
2./ Do you have to use a Combo box? do you have the screen real estate to use a virtual list view instead? (handle the storage and paging yourself)
3./ Create your own Virtual combo box...model the virtualization techniques on the virtual list view.
4./ Cheat...rather than a combo box, use a edit box with a "browse" button that opens a list that you can fill dynamically.
As far as I know there is no mode that lets you do this already with the dev express (or native) combo boxes.
ComboBox 和 ListView 的性能呈指数曲线下降,在处理数千个项目时变得非常糟糕。如果您的列表超过几千个,请尽可能使用虚拟列表。
ComboBoxes and ListViews experience performance degradation on an exponential curve, becoming really bad with thousands of items. Use Virtual lists whenever possible, if you have more than a few thousand.
也许您可以使用 LookupComboBox(也来自 DevExpress)。在这里,您可以将数据加载到组合框引用它的单个数据集中。
Maybe you can use a LookupComboBox (also from DevExpress). Here you can load the data into a single DataSet where the Comboboxs are refering to it.
老实说,对于将 12000 条记录加载到这样的控件中,三秒听起来相当不错。
下拉列表是否必须从 TdxfCustomComboBox 下降?我认为您最好在此处滚动自己的类似组合框的控件,该控件将根据需要分页关联的数据集,而不是预加载所有字符串。理想情况下,您也可以在其中构建过滤功能。
Honestly, three seconds sounds pretty good for loading 12000 records into a control like that.
Does the drop-down have to descend from TdxfCustomComboBox? I think you'd be better off rolling your own combo-box-like control here that would page through an associated dataset as required rather than pre-loading all the strings. Ideally you could build filtering into it too.
这只是一个愚蠢的设计!更好的选择是添加一个用户可以单击的按钮。当他单击它时,会打开一个新表单,其中包含与选项表的连接,并且它将按照您喜欢的方式显示所有选项。然后,用户必须选择一个,可以使用 pageUp/PageDown 和各种过滤器,因为当然,您将使用 DBGrid 来显示选项,然后用户单击“选择”按钮,这将返回所选选项返回。
新表单将提供您所需的所有空间!
从设计的角度来看,任何考虑使用包含 12.000 个选项的下拉列表的人都会被该软件的用户视为傻瓜!不管你做得多快,它肯定会变得非常不受欢迎!你说为什么?因为如果没有额外的搜索选项,用户无法在这么大的列表中找到他们需要的内容!
This is just a foolish design! A better option is to add a button which the user can click on. When he clicks on it, a new form opens with a connection to the options table and it will display all the options in the way you prefer. The user then has to select one, could use pageUp/PageDown and all kinds of filters because -of course- you'd be using a DBGrid to display the options and then the user clicks the "Select" button which will return the selected option back.
A new form would provide all the space you would need!
From a design viewpoint, anyone considering a dropdown list with 12.000 options will be considered a fool by the users of this software! It would definitely make it very unpopular, no matter how fast you make it! Why, you say? Because users can't find what they need in a list that big without additional search options!