15

我知道在 TListBox 等 VCL 控件上使用 BeginUpdate 和 EndUpdate 可以加快使用 Items 填充控件的过程,因为它可以防止控件被重新绘制,直到调用 EndUpdate。

例子:

procedure TForm1.AddItems;
var
  i: Integer;
begin
  Screen.Cursor := crHourGlass;
  try
    for i := 0 to 5000 do
    begin
      ListBox1.Items.Add('Item' + IntToStr(i));
    end;
  finally
    Screen.Cursor := crDefault;
  end;
end;

上面会有延迟,因为允许重新绘制 Listbox,但是可以通过阻止重新绘制来缩短延迟,如下所示:

procedure TForm1.AddItems;
var
  i: Integer;
begin
  Screen.Cursor := crHourGlass;
  try
    ListBox1.Items.BeginUpdate;
    try
      for i := 0 to 5000 do
      begin
        ListBox1.Items.Add('Item' + IntToStr(i));
      end;
    finally
      ListBox1.Items.EndUpdate;
    end;
  finally
    Screen.Cursor := crDefault;
  end;
end;

现在我使用 TStringList 对此进行了测试:

procedure TForm1.AddItems;
var
  SL: TStringList;
  i: Integer;
begin
  SL := TStringList.Create;
  try
    Screen.Cursor := crHourGlass;
    try
      SL.BeginUpdate;
      try
        for i := 0 to 5000 do
        begin
          SL.Add('Item' + IntToStr(i));
        end;
      finally
        SL.EndUpdate;
      end;

      ListBox1.Items.Assign(SL);
    finally
      Screen.Cursor := crDefault;
    end;
  finally
    SL.Free;
  end;
end;

似乎无论 TStringList 是否使用 BegindUpdate 和 EndUpdate,列表的填充速度大致相同。

尽管 TStringList 是在内存中执行而不是在视觉上执行,但它们是否真的需要。无论如何,我是否应该在 TStringList 上使用 BeginUpdate 和 EndUpdate,这样做是一种好习惯吗?

问这个我觉得很傻,但为什么 TStringList 有 BeginUpdate 和 EndUpdate 程序?

我想我可能已经在这里回答了我自己的问题,无论哪种方式,我都想听听您的意见。

谢谢 :)

4

3 回答 3

24

BeginUpdate禁止字符串列表的和OnChanging事件OnChange。根据连接的内容,它可以显着加快速度。

在您的示例中,BeginUpdate/EndUpdate 没有太大区别。使用 TStringlist 实例并将其分配给列表视图是一种非常有效的方法。

于 2012-02-05T16:28:12.960 回答
10

BeginUpdateEndUpdate在抽象基类中引入TStrings。所以TStringList继承了这个能力,即使它不是特别有用。但是,它当然对许多其他TStrings后代有用。

请记住,许多其他TStrings后代都有私有实现。例如,TStrings与 a 关联的对象对于单元TListBox的实现部分是私有的StdCtrlsTListBox控件公开项目列表,TStrings以便使其可用BeginUpdateEndUpdate它们需要在抽象基类中声明。

在我看来,在使用您知道的对象时,您可以放心地忽略这些方法TStringList

现在,关于填充列表视图的代码,我认为使用中间TStringList. 我将直接填充列表视图并在列表视图上使用BeginUpdate/ 。如果列表视图仍然存在性能问题,那么解决方案是虚拟列表视图。EndUpdateItems

于 2012-02-05T16:35:13.737 回答
2

这只是这里解释的锁定模式的实现。

它允许您了解temporarily lock课程的一个方面,避免不必要的通知。

与您在DB.TDataSet.DisableControlsDB.TDataSet.EnableControls中找到的完全相同。

于 2012-02-06T10:51:28.910 回答