将ListView中的Setting Items.Count设置为任何大于100,000,000的数字与将计数设置为0具有相同的结果 - 这是底层Windows控件的限制,还是Delphi特定的?我预期限制应该是约20亿,因为Delphi XE4的文档说限制是(有符号)DWORD的大小(即:2^31-1)。
简单示例:
简单示例:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls;
type
TForm1 = class(TForm)
ListView1: TListView;
procedure ListView1Data(Sender: TObject; Item: TListItem);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
// Assumes ListView1.OwnerData := True;
ListView1.Items.Count := 100000001; // Works if 100000000 is used instead
end;
procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
Item.Caption := Item.Index.ToString();
end;
end.
我进行了一些调查,并直接向底层控件发送LVM_SETITEMCOUNT,但是任何超过100,000,000的LPARAM都会返回错误,并将内部计数设置为0,这使我相信这是底层控件的限制。我无法在任何地方找到相关文档 - 虽然我认为拥有那么多项目并不常见。假设这是控件的限制,应该会提交一个Delphi错误报告,因为TListView在调用失败时没有抛出任何异常 - 它只是默默地中断了一切。
目前,我的解决方法是将listview保持在非虚拟模式下,根据控件的大小(即:VisibleRowCount属性)添加到列表中确切数量的可见项,保持我的数据偏移,并循环遍历列表中的项以基本相同的方式填充列表,就像虚拟模式列表一样,使用自己的滚动条来控制偏移量以实际达到上限约为20亿。
是否有方法解决这种行为?对于处理大量数据和ListView有经验的人能否提供任何见解?