仮想リストビューで100000000件を超える値が設定できない

解決


Nov  2013-02-09 09:41:31  No: 43805

単純に質問です。

仮想リストビューを使用していて、アイテム件数を100000001件に設定できません。
これは仕様なのでしょうか?(integer値であるということしか分かりませんでした)

環境はXE2(Win7-x64)です。


Mr.XRAY  2013-02-10 05:26:52  No: 43806

こんにちは,
想像力をかきたてる素晴らしい質問ですね.頭の体操になります.
具体的にどのような状況なのか,全く分かりませんが,
100000000 なら設定できる,ということでしょうか.

それにしても,すごい数ですね.表示できたとしても,スクロールが大変なような...
ところで,Nov さんの言う「仮想リストビュー」というのはどんなものなのでしょう.

一番簡単で早い解決方法は,「あきらめる」ことですね.

参考
http://mrxray.on.coocan.jp/Others/003.htm


Nov  2013-02-10 06:28:03  No: 43807

説明が全然足りませんでした。

状況としては、TListViewのReportスタイルで、1.5Gbyte程度のファイルを
ダンプリスト(16byte/行)のように表示しようとして壁にぶつかりました。

また、次のような単純化したコードでも確認しました。
ListView1.Items.Count := 100000001; にすると、表示されなくなります。
(デバッガで値を確認すると、0になっていました)

type
  TForm1 = class(TForm)
    ListView1: TListView;
    procedure FormCreate(Sender: TObject);
    procedure ListView1Data(Sender: TObject; Item: TListItem);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListView1.ViewStyle := vsReport;
  ListView1.GridLines := True;
  ListView1.OwnerData := True;
  with ListView1.Columns.Add do begin Caption := 'Index'; Width := 120; end;
  with ListView1.Columns.Add do begin Caption := 'Value'; Width := 200; end;
  ListView1.Items.Count := 100000000; // 100000001 に設定出来ない?
end;

procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
begin
  Item.Caption := IntToStr(Item.Index+1);
  while Item.SubItems.Count<1 do Item.SubItems.Add('');
  Item.SubItems[0] := Format('Value: %d', [Item.Index+1]);
end;


KHE00221  2013-02-10 09:58:06  No: 43808

procedure TForm7.FormCreate(Sender: TObject);
begin
    ListView1.Items.Count := 7; //表示の高さに合わせる
    ListView1.OwnerData := True;
    ListView1.OnData := ListView1Data;

    ScrollBar1.Left := ListView1.Left + ListView1.Width - ScrollBar1.Width - 1;
    ScrollBar1.Top := ListView1.Top + 2;
    ScrollBar1.Height := ListView1.Height - 4;
    ScrollBar1.OnScroll := ScrollBar1Scroll;
    ScrollBar1.Kind := sbVertical;
    ScrollBar1.Max := 200000000 - ListView1.Items.Count; 
end;

procedure TForm7.ListView1Data(Sender: TObject; Item: TListItem);
begin
    Item.Caption := IntToStr(Item.Index + ScrollBar1.Position);
end;

procedure TForm7.ScrollBar1Scroll(Sender: TObject; ScrollCode: TScrollCode;
  var ScrollPos: Integer);
begin
    ListView1.Invalidate;
end;


HOta  2013-02-10 17:05:44  No: 43809

TListViewはTStringsからの派生で、Countプロパティは読み取り専用ではないでしょうか?


DEKO  2013-02-10 17:20:05  No: 43810

> これは仕様なのでしょうか?

[Virtual Mode ListView (Code Project)]
http://www.codeproject.com/Articles/42229/Virtual-Mode-ListView

[Is WinForms ListView in VirtualMode limited to 100,000,000 rows? (Stack Overflow)]
http://stackoverflow.com/questions/2454942/is-winforms-listview-in-virtualmode-limited-to-100-000-000-rows

仕様っぽいですね。


Mr.XRAY  2013-02-10 18:51:51  No: 43811

やってみました.
これは,「設定できない」というより,表示しないんですね.
前に,何かのコントロールが,行数の制限,という記憶がうっすらとあり,
探してみたのですが,見つかりませんでした.記憶違いかも知れません.


Nov  2013-02-10 19:38:47  No: 43812

Mr.XRAYさん、KHE00221さん、HOtaさん、DEKOさん、ありがとうございました。

アイテム限度数については、msdnに記述は無くても、既知の情報だったんですね...

ListView自体の機能はあきらめるしかありませんが、おかげさまで、KHE00221さんの方法で、問題は回避できました。

結論としては、
(1) Win7の環境において、ListViewのアイテム限度数は100,000,000件(公式記述は無い)。
(2) アイテム限度数を超える場合の対処法として、ListViewのスクロール機能を使わずに、
    スクロールバーコントロールと組み合わせる方法がある。
ということで、解決にしたいと思います。

ListViewのスクロール機能を使わないという手法は、自分には気づけない方法でした、ありがとうございます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加