2012-04-20 1 views
0

Я хотел бы запрограммировать следующую ситуацию:TListItem Объекты

У меня есть 2 разных ListViews в форме. Я хотел бы добавить определенные элементы из 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 (и он должен также удалить дочерние элементы ...)

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', не может работать. Как только функция вернется, poof, эта переменная исчезла. Поэтому вам нужно будет положить их в кучу. Но получить представление списка, чтобы иметь это, кажется плохой идеей. Вам нужен вид виртуального списка. –

+0

любая идея, как я мог это сделать без виртуального списка? –

+2

Ну, я бы использовал TListItem.Data в качестве своего хранилища. И вам нужна куча выделенной вещи. Вероятно, экземпляр класса. Но это так тяжело. Почему бы вам не сделать это правильно с помощью виртуальной парадигмы. Ты никогда не оглянешься. Является ли представление списка действительно вашей основной структурой данных? –

ответ

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; 
+0

работает как шарм. Большое спасибо. :) –

Смежные вопросы