virt------------ |
Отправлено: 20.03.2007, 19:52 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 15
|
(с TTreeView мало знаком)
Проблема:
Структуру подгружаю из файла.
Для некоторых узлов нужно изменить картинки (Statelndex)
- Как мне пройти по всему дереву?
(По возможности пример) |
|
desivers |
Отправлено: 20.03.2007, 20:08 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 32
|
Есть свойство Count возвращает количество нодов
обратится к ноде по индексу можно так
TreeView->Items->Item[i]
пройтись можно в цикле
for (int i = 0; 0<= TreeView->Count; i++)
{
if (условие)
TreeView->Items->Item[i]->StateImage = 0;
}
Отредактировано desivers — 20.03.2007, 20:10 |
|
Ramzay |
Отправлено: 20.03.2007, 21:26 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 31
|
Если емеешь дело с иерархической структурой (деревом), тебе без рекурсии не обойтись. Под рукой нет программы на BCB, но выглядит это приблизительно так:
1) Тебе нужно написать функцию (SetBranch), которая будет получать узел и для его подузлов будет устанавливать Statelndex.
2) После установки Statelndex функция вызывает сама себя с параметром "текущий подузел".
CODE |
. . .
for(int i=0; i<TreView1->Items->Count; i++) // цикл перебора узлов самого верхнего уровня дерева
{
if (условие)
TreeView->Items->Item[i]->StateImage = 0;
SetBranch(TreeView->Items->Item[i]); // установить StateImage на подузлах узла TreeView->Items->Item[i]
}
. . .
//------------------------------------------------------------------------
// устанавливает StateImage на подузлах узла CurNode
//------------------------------------------------------------------------
SetBranch(TTreeNode* CurNode)
{
for (int i = 0; i< CurNode->Count; i++) // перебирает подузлы узла CurNode
{
TTreeNode* CurSubNode = CurNode->Item[i]; // текущий подузл узла CurNode
if (условие)
CurSubNode->StateImage = 0; // делаем то, что нам нужно
SetBranch(CurSubNode); // установить StateImage на подузлах узла CurSubNode
}
}
| |
|
virt------------ |
Отправлено: 22.03.2007, 21:21 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 15
|
Спасибо!!!
[Только получилось выйти в инет...]
Еще пару вопросов
1) Я так понял в TreeView используется для каждого узла Имя и data
т.е. Имя <-> Data
...как при добовлении узла записать data (в частности значения типа int) и потом при нажатии на имя выводилась data?
2) Как создать узел в определенном месте...
т.е. вид пути к узлу "qwer\wer\qw" "Имя1"
Т.е. при создании разлаживаем "qwer\wer\qw" на три узла и создаем "Имя 1" — С этим проблем нет, но как быть если есть "qwer\wer\qw" "Имя2" при этом они не идут в подрят.
Т.е. нужно определить есть ли "qwer"
нет — создаем ... всё
есть- проверяем естли в нем "wer"
___ нет — создаем оставшееся
___ да-проверяем естли в нем "qw"
...
Т.е. по факту нужно найти родителя с именем, потом ребенка, потом опять ребенка...
Как это сделать?
|
|
desivers |
Отправлено: 22.03.2007, 21:41 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 32
|
ЛОЛ. Только неделю назад реализовал подобное в дипломном, но зас хочу уйти от такой схемы.
вобщем смысыл такой я беру строку из БД разбираю ее, а дальще как ты написал разбирайся
CODE |
void __fastcall TFormMain::NextLines()
{
AnsiString Buff = "", Path = "";
TTreeNode *FocusNode, *TempNode;
bool CreateNode = false, FirstWord = true;
Path = ADOQueryPrimaryPath->Value;
for (int i = 1; i <= Path.Length(); i++)
{
if (Path[i] == '\\')
{
if (FirstWord == true)
{
TempNode = TreeView->Items->GetFirstNode();
while (TempNode)
{
if (TempNode->Text == Buff)
{
FocusNode = TempNode;
break;
}
TempNode = TempNode->getNextSibling();
}
if (!TempNode)
{
FocusNode = TreeView->Items->AddChild(NULL, Buff);
CreateNode = true;
}
FirstWord = false;
}
else
{
if (CreateNode == true)
FocusNode = TreeView->Items->AddChild(FocusNode, Buff);
else
{
if (FocusNode->Count == 0)
{
FocusNode = TreeView->Items->AddChild(FocusNode, Buff);
CreateNode = true;
}
else
{
TempNode = FocusNode->getFirstChild();
while (TempNode)
{
if (TempNode->Text == Buff)
{
FocusNode = TempNode;
break;
}
TempNode = TempNode->getNextSibling();
}
if (!TempNode)
{
FocusNode = TreeView->Items->AddChild(FocusNode, Buff);
CreateNode = true;
}
}
}
}
Buff = "";
}
else
Buff = Buff + Path[i];
}
if (ADOQueryPrimaryFolder->Value == true)
{
if (FirstWord == true)
TreeView->Items->AddChild(NULL, Buff);
else
{
if (CreateNode == true)
FocusNode = TreeView->Items->AddChild(FocusNode, Buff);
else
{
if (FocusNode->Count == 0)
{
FocusNode = TreeView->Items->AddChild(FocusNode, Buff);
CreateNode = true;
}
else
{
TempNode = FocusNode->getFirstChild();
while (TempNode)
{
if (TempNode->Text == Buff)
{
FocusNode = TempNode;
break;
}
TempNode = TempNode->getNextSibling();
}
if (!TempNode)
{
FocusNode = TreeView->Items->AddChild(FocusNode, Buff);
CreateNode = true;
}
}
}
}
}
else
{
if (FirstWord == true)
{
FocusNode = TreeView->Items->AddChild(NULL, Buff);
FocusNode->ImageIndex = 1;
FocusNode->SelectedIndex = 1;
}
else
{
FocusNode = TreeView->Items->AddChild(FocusNode, Buff);
FocusNode->ImageIndex = 1;
FocusNode->SelectedIndex = 1;
}
}
FirstWord = true;
CreateNode = false;
Buff = "";
} | |
|
virt------------ |
Отправлено: 23.03.2007, 20:04 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 15
|
Спасибо |
|
Ramzay |
Отправлено: 23.03.2007, 20:22 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 31
|
QUOTE (virt------------ @ 22.03.2007, 21:21) | 1) Я так понял в TreeView используется для каждого узла Имя и data
т.е. Имя <-> Data
...как при добовлении узла записать data (в частности значения типа int) и потом при нажатии на имя выводилась data?
|
Data имеет тип void* и является указателем на что-либо. Если ты хочешь поставить в соответствие узлу переменную int, то значению этого указателя нужно присвоить адрес int-переменной.
CODE |
int aaa=10; // переменная типа int;
CurNode->Item[i]->Data=&aaa; //Присваиваем адрес переменной
int bbb = *((int*)CurNode->Item[i]->Data); // Переменная bbb получает заначение 10
|
С именем все намного проще. CurNode->Item[i]->Text="Этот текст будет виден на узле дерева";
Отредактировано Ramzay — 23.03.2007, 20:25 |
|