2012-04-20 5 views
0

다음 상황을 프로그래밍하고 싶습니다.TListItem 개체

두 개의 서로 다른 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; 

어떤 아이디어를 실현할 수 있습니까?

+3

할당 된 스택 'TITEMS'이 (가) 작동하지 않습니다. 함수가 반환하자마자, 그 변수는 사라졌습니다. 그래서 힙에 놓아야합니다. 그러나 이것을 소유하게 목록보기를 얻는 것은 나쁜 생각처럼 보입니다. 가상 목록보기를 원합니다. –

+0

가상 목록보기없이 어떻게 할 수 있습니까? –

+2

글쎄, 나는 TListItem.Data를 나의 스토리지로 사용할 것이다. 그리고 힙 할당 작업이 필요합니다. 아마 클래스의 인스턴스. 그러나 그것은 그렇게 어려운 것입니다. 가상 패러다임으로 제대로하지 않는 이유는 무엇입니까? 너는 결코 되돌아 보지 않을 것이다. 목록보기가 실제로 기본 데이터 구조입니까? –

답변

3

스택의 로컬이 아닌 힙에 항목 목록을 동적으로 할당해야하므로 사용하는 동안 메모리에 유효합니다.

배열 대신 TList을 사용하는 것이 좋습니다. 역 동성을 할당하는 것이 더 쉽습니다. 또한 속성을 다른 용도로 사용하지 않는 한 TListItem.SubItems.Objects[] 속성 대신 TListItem.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; 
+0

은 매력처럼 작동합니다. 고맙습니다. :) –