为什么TStringList有BeginUpdate和EndUpdate?

13 delphi library-design

我知道在TLI控件(如TListBox)上使用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;
Run Code Online (Sandbox Code Playgroud)

上面会有延迟,因为允许重新绘制列表框,但是可以通过防止重新绘制来缩短延迟:

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;
Run Code Online (Sandbox Code Playgroud)

现在我使用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;
Run Code Online (Sandbox Code Playgroud)

似乎无论TStringList使用BegindUpdate和EndUpdate,列表都以大致相同的速度填充.

它们是否真的需要,因为TStringList是在内存中执行而不是在视觉上执行.无论如何我应该在TStringList上使用BeginUpdate和EndUpdate,这样做是不错的做法?

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

我想我可能已经在这里回答了我自己的问题,无论我想听听你的意见.

谢谢 :)

Uwe*_*abe 21

BeginUpdate抑制OnChangingOnChange对的StringList的事件.根据连接的内容,它可以显着加快速度.

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


Dav*_*nan 10

BeginUpdateEndUpdate在抽象基类中引入TStrings.因此TStringList即使它不是特别有用,也会继承此功能.但是,它对许多其他TStrings后代当然有用.

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

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

现在,关于填充列表视图的代码,我认为使用中间件没有任何意义TStringList.我只想直接填充列表视图和利用BeginUpdate/ EndUpdate列表视图Items.如果列表视图仍然存在性能问题,则解决方案是虚拟列表视图.