Изучение компонента TTreeView, часть I
Теперь посмотрим, как можно удалить узел. Когда мы добавляли узел, то метод Add возвращал ссылку на вновь создаваемый узел. Если ссылку запомнить в переменной типа TtreeNode, то затем эту переменную можно использовать для удаления узла. Вот так:
tomGordonNode->Delete();
Замечание: вызывая метод Delete() для узла который имеет потомков надо иметь виду, что вместе с узлом удалятся и все потомки до последнего колена.
Можно удалить всех потомков родительского узла кроме собственно самого узла, используя метод DeleteChildren().
Пример:
bostonPitchers->DeleteChildren();
Добавление и удаление узлов связанных с объектами
Когда мы раньше говорили о дереве узлов, то обращали внимание на то, что узел может быть связан с каким-либо объектом. Можно установить связь вновь создаваемого узла с объектом, используя группу методов альтернативных Add и Insert, которые получают в качестве параметра типа *void ссылку на объект. Вот эти методы:
" AddObject
" AddObjectFirst
" AddChildObject
" AddChildObjectFirst
" InsertObject
Синтаксис незначительно отличается лишь включением третьего параметра типа void*:
TTreeNode* __fastcall AddObject(TTreeNode* Node,const System::AnsiString S, void * Ptr);
Методы Add и Insert как бы имитируют связь с объектами, устанавливая пустым void* параметр, указывающий на то, что объект не представлен. Кроме использования указателя в методах Add и Insert, можно установить и использовать указатель, применяя свойство узла - Data:
Stats *newStats = new Stats();
tomGordonNode = TreeView1->Items->AddObject(pedroMartinezNode, "Tom Gordon",
newStats);
или
tomGordonNode->Data = (void*) newStats;
Также следующий код возвращает объект:
Stats* tomsStats = (Stats*) tomGordonNode->Data;
Возможность связать узел с любым объектом добавляет возможности программирования. Однако использовать свойство Data надо осторожно. Например, метод Delete не освобождает область памяти, связанную с типом void*, программист сам должен позаботиться об этом. Ниже пример как это сделать:
Stats* tomsStats = (Stats*) tomGordonNode->Data;
delete tomsStats;
tomGordonNode->Delete();
Если надо удалить объект, но оставить узел (по сути, разорвать связь узла с объектом), то лучшим способом будет установка в NULL указателя на Data. Вот так:
Stats* tomsStats = (Stats*) tomGordonNode->Data;
delete tomsStats;
tomGordonNode->Data = (void*) NULL;
Навигация по дереву
Для нахождения узлов во время выполнения есть много методов. Методы делятся на: позиционные и абсолютные. Начнем с позиционных.
Примечание: некоторые методы, такие как getFirstChild, getNextSiblink, getPrevSiblink не выполняются при написании с большой буквы, в отличие от других методов. Это баг С++ Builder.