Delphi将项目添加到组合框速度

Delphi将项目添加到组合框速度,delphi,combobox,performance,Delphi,Combobox,Performance,我有一个相当复杂和大型的应用程序,可以处理大量的数据。有没有一种快速的方法可以在组合框中添加不需要太长时间的项目?在我的P3 3.2ghz上,下面的代码片段只需不到一秒钟就可以添加大约32000个项目。(MasterCIList是一个字符串列表,字符串长度通常为20-30字节) 深入到VCL,似乎在tcomboxstrings.Add中,有一个调用 Result := SendMessage(ComboBox.Handle, CB_ADDSTRING, 0, Longint(PChar(S)))

我有一个相当复杂和大型的应用程序,可以处理大量的数据。有没有一种快速的方法可以在组合框中添加不需要太长时间的项目?在我的P3 3.2ghz上,下面的代码片段只需不到一秒钟就可以添加大约32000个项目。(MasterCIList是一个字符串列表,字符串长度通常为20-30字节)

深入到VCL,似乎在
tcomboxstrings.Add
中,有一个调用

Result := SendMessage(ComboBox.Handle, CB_ADDSTRING, 0, Longint(PChar(S)));
我猜这真的占用了时间(好吧,我知道是的)。是否有其他方法可以更快地填充项目?有高速组合框吗?我有TMS组件,但它们似乎是Tcombox的扩展

例如,我有一个PlusMemo,它似乎是对TMemo的完全重写。我可以很容易地在一秒钟内将一百万行添加到PlusMemo中。我不这么认为

非常感谢您抽出时间

也许cmb.Items.Assign(myStringList)会有所帮助

这里有一个疯狂的想法:我还没有尝试过,但是你可以检查一下是否有一种方法可以通过设置项目数,然后设置所有者图形来虚拟加载组合框。请原谅这个疯狂的想法,但我想我已经听说了它的存在。无关:这是Palm操作系统中的操作方式…加载组合框的更快方法是不加载所有组合框…;-)


不是答案,但你到底为什么想要32000个项目在一个组合框中?这是存储那么多数据的糟糕方式


我同意;这是一个糟糕的做法…

如果我是一个讨厌的人,我很抱歉,但我怀疑一个包含32000个项目的TComboBox甚至是远程“可用的”--我想说它之所以慢是有原因的:它从来没有打算这么做:)

是否有可能过滤数据,只加载一个子集?更具体地说,在我一直在开发的一个特定数据库应用程序中,用户可以搜索一个人。我们让用户键入至少3或4个字符的名称,然后才开始在列表框中返回结果。这大大提高了搜索表单的可用性,也大大加快了整个过程

你能采用类似的方法吗


或者,换一种完全不同的方式,也许你可以看看这个组件——直接使用,或者灵感来源。

我同意,组合框中有32K个项目是一个荒谬的数字。。。也就是说,您可以先尝试将项目添加到TStringList,然后使用Begin/EndUpdate和AddString的组合:

SL := TStringList.Create;
try
  // Add your items to the stringlist
  ComboBox.Items.BeginUpdate;
  try
    ComboBox.Items.AddStrings(YourStringList);
  finally
    ComboBox.Items.EndUpdate;
  end;
finally
  SL.Free;
end;
代码可以编译,但我没有进一步测试它;我从未觉得有必要在组合框或列表框中添加超过几十个项目。如果可能需要更多的项目,我会在填充列表之前找到一种过滤方法,以减少项目


出于好奇,您希望用户如何通过对这么多项目进行排序来做出决定?

又是我。我正在添加32000项,因为我需要。这是我的应用程序中有“很多”项的许多控件之一。我需要那么多东西。它的工作只是好看的东西了。事实上是完美的。我只是想优化一下。用户发现事情很好,因为它们是按照一定的逻辑顺序进行的

到目前为止,我对Assign和AddStrings所做的一切都是,它们最终会在SendMessage调用中添加。所以我会继续找的


感谢您的反馈。

也许您可以在后端使用数据库引擎并使用数据感知组件。这样一来,事情会变得更快、更实用。也许,如果你能描述一下你试图实现的目标,我们会进一步帮助你。在任何情况下,你的UI设计都很奇怪。对于这一点,可能会帮助您更好。

我以不同的方式实现这一点。首先,我删除了combobox控件并获取textbox控件,并将其自动完成分配给自定义源,其中自定义源字符串集合为32k项。我从控件验证的新查询中获取所选值

因此,它可以取代组合框功能。主要是关于32k项目,人们不会滚动,但他们会不断输入按键,并被我们的自定义自动完成源捕获。

用于添加主列表项目。完成添加项目后,仅使用添加字符串

procedure TForm2.BackgroundWorker1Work(Worker: TBackgroundWorker);
var
  I: Integer;
begin
  MasterCIList.BeginUpdate;
  try
    MasterCIList.Capacity := 32 * 1024; // if derminate  count of items
    for I := 1 to 32 * 1024 do
    begin
      MasterCIList.Add(IntToStr(I));
      { if need progess }
      if I mod 300 = 0 then
        Worker.ReportProgress((I * 100) div MasterCIList.Capacity);
      { if need cancelable }
      if (I mod 100 = 0) and Worker.CancellationPending then
        Break;

    end;

  finally
    MasterCIList.EndUpdate;
  end;

end;

procedure TForm2.BackgroundWorker1WorkComplete(Worker: TBackgroundWorker;
  Cancelled: Boolean);
begin

  LookupComboBox.Items.AddStrings(MasterCIList );


// AddStrings use beginupdate..endupdate in itself

 end;

也许你可以试试这个

“加快向组合框或列表框添加项目”
var
缓冲区:TStringList;
开始
Buffer:=TStringList.Create;
尝试

//-->“将项目添加到缓冲区”这里不是答案,但为什么您希望组合框中包含32000个项目?这是存储这么多数据的糟糕方法。这是一个很好的提示。可能会在OnDropDown处理程序中添加字符串,并以已输入的字符开始过滤。这样,用户对延迟有影响。在任何情况下,一个包含32000项的查找列表都是不可用的,即使是立即填充的。编辑你原来的帖子。第二,同样,我已经编程20多年了,赢得了15+的应用,做了一些非常复杂的应用,从来没有发现在组合框中甚至需要1K个项目。但祝你(和你应用程序的用户)好运。同意肯的观点。说清楚一点——如果答案真的是对你的问题的回答,那么发布一个答案是可以的。如果您有意见,请编辑您的问题。
procedure TForm2.BackgroundWorker1Work(Worker: TBackgroundWorker);
var
  I: Integer;
begin
  MasterCIList.BeginUpdate;
  try
    MasterCIList.Capacity := 32 * 1024; // if derminate  count of items
    for I := 1 to 32 * 1024 do
    begin
      MasterCIList.Add(IntToStr(I));
      { if need progess }
      if I mod 300 = 0 then
        Worker.ReportProgress((I * 100) div MasterCIList.Capacity);
      { if need cancelable }
      if (I mod 100 = 0) and Worker.CancellationPending then
        Break;

    end;

  finally
    MasterCIList.EndUpdate;
  end;

end;

procedure TForm2.BackgroundWorker1WorkComplete(Worker: TBackgroundWorker;
  Cancelled: Boolean);
begin

  LookupComboBox.Items.AddStrings(MasterCIList );


// AddStrings use beginupdate..endupdate in itself

 end;
var
  Buffer: TStringList;
begin
  Buffer := TStringList.Create;

  try
    // --> Add items to Buffer here <--

    ComboBox.Items := Buffer;
  finally
    FreeAndNil(Buffer);
  end;
end;