1

次の状況をプログラムしたいと思います。

フォームに2つの異なるListViewがあります。ListView2の特定のアイテムをListView1アイテムに添付したいと思います。「親」アイテムが削除された後、ListView2からすべての添付アイテムも削除する必要があります。私はこれまでこれを試しました:

type
 TITEMS = record
 A_Items : array of TListItem;
end;

ListView1にアイテムを追加するボタン(ParentItems)

var
 item : TListItem;
begin
 item := ListView1.Items.Add;
 item.Caption := 'ParentTestItem';
 item.SubItems.Add('TestSubItem');

ListView2(ChildItems)にアイテムを追加するボタン

 var
  item : TlistItem;
  items : TITEMS;
 begin
  if ListView1.Selected = NIL then exit; // Make sure an item is selected.
  item := ListView2.Items.Add;
  item.Caption := 'ChildTestItem';
  item.SubItems.Add('TestSubItem');
  SetLength (items.item, Length(items.item) + 1); // wrong? 
  items.item[Length(items.item)-1] := item;
  ListView1.Selected.SubItems.Objects[0] := @items;

ParentItemを削除するボタン(そしてChildItemsも削除する必要があります...)

  var
   items : TItems;
   i : Integer;
   item : TlistItem;
  begin
   if ListView1.Selected = NIL then exit; // Make sure an item is selected.
   items := TItems(ListView1.Selected.SubItems.Objects[0]); // Cast
   for i := 0 to Length (items.item) - 1 do begin
    item := items.item[i];
    item.Delete;
   end;
   ListView1.Selected.Free;

どうすればこれを実現できるか考えてみてください。

4

1 に答える 1

3

アイテムのリストは、スタック上でローカルにではなく、ヒープ上で動的に割り当てる必要があるため、使用中はメモリ内で有効なままです。

配列の代わりに使用することをお勧めしTListます。動的に割り当てる方が簡単です。TListItem.Dataまた、プロパティの代わりにプロパティを使用することをお勧めしTListItem.SubItems.Objects[]ます(既に他の目的でプロパティを使用している場合を除くData)。

procedure TForm1.AddParentBtnClick(Sender: TObject);
var 
  item : TListItem; 
begin 
  item := ListView1.Items.Add; 
  item.Caption := 'ParentTestItem'; 
  item.SubItems.Add('TestSubItem'); 
end;

procedure TForm1.AddChildBtnClick(Sender: TObject);
var 
  Selected, item : TListItem; 
  items : TList; 
begin 
  Selected := ListView1.Selected;
  if Selected = nil then Exit; // Make sure an item is selected. 

  items := TList(Selected.Data);
  if items = nil then begin
    items := TList.Create;
    Selected.Data := items;
  end;

  item := ListView2.Items.Add; 
  try
    item.Caption := 'ChildTestItem'; 
    item.SubItems.Add('TestSubItem'); 
    items.Add(item); 
  except
    item.Delete;
    raise;
  end;
end;

procedure TForm1.DeleteParentBtnClick(Sender: TObject);
var
  Selected : TListItem; 
begin
  Selected := ListView1.Selected;
  if Selected <> nil then Selected.Delete;
end;

procedure TForm1.ListView1Deletion(Sender: TObject; Item: TListItem);
var 
  items : TList; 
  i : Integer; 
begin 
  items := TList(Item.Data); // Cast 
  if items <> nil then begin
    for i := 0 to items.Count - 1 do begin 
     TListItem(items[i]).Delete; 
    end; 
    items.Free;
    Item.Data := nil;
  end;
end;
于 2012-04-20T22:58:52.240 に答える