Delphi 使用EasyListView调用LVItemGetCaption时显示项目?

Delphi 使用EasyListView调用LVItemGetCaption时显示项目?,delphi,listview,virtual,Delphi,Listview,Virtual,我正在尝试使用实现虚拟数据模式 从演示中: procedure TForm1.AddItems(Count: Integer); var i: Integer; begin // Add items to the listview. Actually the items are added to the first // group. This group is created automatically when the first item is added. LV.Begi

我正在尝试使用实现虚拟数据模式

从演示中:

procedure TForm1.AddItems(Count: Integer);
var
  i: Integer;
begin
  // Add items to the listview. Actually the items are added to the first
  // group. This group is created automatically when the first item is added.
  LV.BeginUpdate;
  try
    for i := 0 to Count - 1 do
      LV.Items.AddVirtual;
  finally
    LV.EndUpdate;
  end;
end;

procedure TForm1.LVItemGetCaption(Sender: TCustomEasyListview;
  const Item: TEasyItem; Column: Integer; var Caption: WideString);
begin
  case Column of
    0: Caption := 'Item ' + IntToStr(Item.Index);
    1: Caption := 'Detail ' + IntToStr(Item.Index);
  end;
end;
如果我添加了一些字符串项:

procedure TForm1.AddItems(Count: Integer);
var
  i: Integer;
begin
  // Add items to the listview. Actually the items are added to the first
  // group. This group is created automatically when the first item is added.
  LV.BeginUpdate;
  try
    for i := 0 to Count - 1 do
    begin
      LV.Items.AddVirtual.Caption := 'DISPLAY ME ' + IntToStr(i);
    end;
  finally
    LV.EndUpdate;
  end;
end;
调用LVItemGetCaption时,如何获取和显示存储的虚拟标题(=字符串)


如果我使用
caption:=LV.Items.Items[Item.Index].caption获取标题然后堆栈溢出。

必须将数据对象添加到项中。例如:

type
  TMyData = class
    Caption: string;
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  item: TEasyItemVirtual;
  MyData: TMyData;
begin
  EasyListview1.BeginUpdate;
  try
    for i := 0 to 100 - 1 do
    begin
      MyData := TMyData.Create;
      MyData.Caption := Format('My Item %D',[i]);
      item := EasyListview1.Items.AddVirtual;
      item.Data := MyData;
    end;
  finally
    EasyListview1.EndUpdate;
  end;
end;

procedure TForm1.EasyListview1ItemGetCaption(Sender: TCustomEasyListview; Item: TEasyItem;
  Column: Integer; var Caption: WideString);
begin
  case Column of
    0: Caption := TMyData(Item.Data).Caption;
    1: Caption := TMyData(Item.Data).Caption;
  end;
end;
不要忘记释放您的对象:

procedure TForm1.EasyListview1ItemFreeing(Sender: TCustomEasyListview; Item: TEasyItem);
begin
  if Assigned(Item.Data) then
    Item.Data.Free;
end;
虚拟节点是不存储数据的节点。它们只是您希望在程序的其他数据结构中已经拥有的数据的视图。当控件需要显示节点时,它会通过触发OnItemGetCaption事件询问程序应该使用什么文本


事实上,它会在需要知道Caption属性值的任何时候调用事件,因此当您试图通过获取标题值来处理标题获取事件时,您会触发无限递归。

您能告诉我Rob,无限递归的坏处是什么吗?那么,使用虚拟节点是个坏主意吗?无限递归的坏主意是没有无限的堆栈空间,因此最终会出现堆栈溢出,正如您所观察到的。使用虚拟节点不是个坏主意。这是个好主意。但是如果您这样做,您必须意识到节点本身不会存储您的数据。这就是重点。您应该已经有了一个数据结构,可以在其中管理程序的数据。列表视图控件仅提供该数据的视图。阅读您最喜欢的设计模式参考中的“模型-视图-控制器”模式。嗨,Linas,我如何更改/更新虚拟节点中标题的值?例如,我有一个按钮可以将第一条记录中的文本从
My Item
更改为
Your Item
。我只看到InsertVirtual方法。只需将Item.Data强制转换为您的类型并设置标题:TMyData(EasyListview1.Items[0].Data)。标题:='your Item';EasyListview1.Items[0]。无效(True);。