IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

 
 Ответить  Открыть новую тему 
> Проблема с компонентом TreeView, C++ builder
сообщение
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской
Реальное имя: Александр

Репутация: -  0  +


Добрый день!

Необходимо заполниль дерево с помощью компонента TreeView, имя элемента дерева должно состоять из номеров и имен, т.е. например дерево должно выглядеть следующим образом:

Код
1имя1
2имя2
3имя3
   3.1имя4
   3.2имя5
      3.2.1имя6
4имя7
   4.1имя8


таким образом чтобы и дочерние и родительские элементы имели порядковый номер.
Столкнулся с такой проблемой что нумерация при добавлении дочернего элемента начинается с 0

Родительские элементы нумеруются нормально, а вот с дочерними проблема

void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString name, roditelb;
TTreeNode *node;

if (TreeView1->Items->Count == 0) // добавление первого элемента
{
name = "1:";
name += Edit1->Text+":";
name += ComboBox1->Items->Strings[ComboBox1->ItemIndex];
TreeView1->Items->Add(NULL,name);
}
else
{
if (RadioGroup1->ItemIndex == 0) /// добавление родительских элементов
{
name = IntToStr(TreeView1->Items->Count+1)+":";
name += Edit1->Text+":";
name += ComboBox1->Items->Strings[ComboBox1->ItemIndex];
TreeView1->Items->Add(NULL,name);
}

if (RadioGroup1->ItemIndex == 1) /// добавление дочерних элементов
{
selected2++;
name = IntToStr(selected2)+":";
name = Edit1->Text+":";
name += ComboBox1->Items->Strings[ComboBox1->ItemIndex];
TreeView1->Items->AddChild(TreeView1->Selected,name);
}
}
}




Спасибо за помощь.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


name = IntToStr(selected2)+":";
name = Edit1->Text+":"; // тут опечатка у тебя? может по этому и не правильно?
name += ComboBox1->Items->Strings[ComboBox1->ItemIndex];
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Пионер
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской
Реальное имя: Александр

Репутация: -  0  +


Да действительно опечатка, но это всего лишь добаляет имя, тоесть у меня имя берется их 2х компонентов Edit и ComboBox, я просто уже поразному пробывал, текст был закоментирован, я не заметил, если исправить все равно не работает.

Сообщение отредактировано: ninja -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


присоедини весь проект, а то лень создавать самому smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Гость






А дочерние можно нумеровать, используя не selected2 (непонятно где и как описанный), а:

		if (RadioGroup1->ItemIndex == 1) /// добавление дочерних элементов
{
name = IntToStr(TreeView1->Selected->Count)+":";
name += Edit1->Text+":";
name += ComboBox1->Items->Strings[ComboBox1->ItemIndex];
TreeView1->Items->AddChild(TreeView1->Selected,name);
}


TreeView1->Selected->Count вернет тебе количество дочерних элементов у Selected, не надо ничего считать вручную, все уже посчитано... Получить из Selected строку до двоеточия и добавить ее в начало нового элемента - не самая большая проблема, правда?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Пионер
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской
Реальное имя: Александр

Репутация: -  0  +


Вот проект:

Прикрепленный файл  TreeView.rar ( 7.07 килобайт ) Кол-во скачиваний: 378


Владимир спасибо Вам огромное все прекрасно работает, как то я проглядел этот свойство у TreeView

Сообщение отредактировано: ninja -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Пионер
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской
Реальное имя: Александр

Репутация: -  0  +


Еще такой вопрос: как реализовать создание пунктов меню на основе полученного дерева? т.е Мне необходимо создать, используя компонент MainMenu, пункты меню, учитывая все уровни вложенности полученного дерева, не могу понять как мне это сделать.

получилось пока следующее:

TMenuItem *Menu;

for (i = 0; i < TreeView1->Items->Count; i++)
{
Menu = new TMenuItem(0);
Menu->Caption = "Пункт меню " + IntToStr(i+1);
MainMenu1->Items->Add(Menu);
}
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гость






Так лень мне Билдер запускать... Дельфи открытая, поэтому сделаю здесь (переносится на Билдер практически один в один)

procedure BuildMenu(node: TTreeNode; menu: TMenuItem);
var
NewMenu, NewSubMenu: TMenuItem;
TVnode: TTreeNode;
begin
TVnode := node;
while TVnode <> nil do
begin
if TVnode.HasChildren then
begin
NewSubMenu := TMenuItem.Create(menu);
NewSubMenu.Caption := TVnode.Text;
BuildMenu(TVnode.GetFirstChild, NewSubMenu);
menu.Add(NewSubMenu);
end
else
begin
NewMenu := TMenuItem.Create(menu);
NewMenu.Caption := TVnode.Text;
menu.Add(NewMenu);
end;
TVnode := TVnode.GetNextSibling;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var CurrMenu: TMainMenu;
begin
CurrMenu := TMainMenu.Create(Form1);
BuildMenu(TreeView1.Items.GetFirstNode, CurrMenu.Items);
Form1.Menu := CurrMenu;
end;
Вот и все...

Проверял до 5-го уровня вложенности - работает нормально...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Пионер
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской
Реальное имя: Александр

Репутация: -  0  +


Владимир спасибо, на делфи все отлично работает, я в Билдер перенес, но почему-то ничего не создается, вроде все проверил, по нажатию на кнопку никакой реакции....

void BuildMenu (TTreeNode *node, TMenuItem *menu)
{
TMenuItem *NewMenu, *NewSubMenu;
TTreeNode *TVnode;

TVnode = node;

while (TVnode != NULL)
{
if (TVnode->HasChildren)
{
// NewSubMenu = TMenuItem->Create(menu);

NewSubMenu = new TMenuItem(menu);
NewSubMenu->Caption = TVnode->Text;
BuildMenu(TVnode->getFirstChild(), NewSubMenu);
menu->Add(NewSubMenu);
}
else
{
//NewMenu := TMenuItem.Create(menu);

NewSubMenu = new TMenuItem(menu);
NewMenu->Caption = TVnode->Text;
menu->Add(NewMenu);
}
TVnode = TVnode->getNextSibling();
}
}


void __fastcall TForm1::Button3Click(TObject *Sender)
{

TMainMenu *CurrMenu;

CurrMenu = new TMainMenu(Form1);
BuildMenu(TreeView1->Items->GetFirstNode(), CurrMenu->Items);
Form1->Menu = CurrMenu;

}


 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Гость






Значит, плохо перевел:

void BuildMenu(TTreeNode *node, TMenuItem *menu)
{
TTreeNode *TVnode = node;
while(TVnode)
{
if(TVnode->HasChildren)
{
TMenuItem *NewSubMenu = new TMenuItem(menu);
NewSubMenu->Caption = TVnode->Text;
BuildMenu(TVnode->getFirstChild(), NewSubMenu);
menu->Add(NewSubMenu);
}
else
{
TMenuItem *NewMenu = new TMenuItem(menu);
NewMenu->Caption = TVnode->Text;
menu->Add(NewMenu);
}
TVnode = TVnode->getNextSibling();
}
}


void __fastcall TForm1::Button3Click(TObject *Sender)
{
TMainMenu *CurrMenu = new TMainMenu(Form1);
BuildMenu(TreeView2->Items->GetFirstNode(), CurrMenu->Items);
Form1->Menu = CurrMenu;
}

только что у меня отработало прекрасно... Только не надо говорить, что это то же самое, хорошо? Это совсем не то же самое smile.gif
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Пионер
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской
Реальное имя: Александр

Репутация: -  0  +


Да действительно не тоже самое, Вы при объявлении переменный сразу присваиваете ей начальное значение, т.е выделяете память для нового объекта, Владимир не могли бы Вы мне объяснить почему именно так работает, а как у меня нет? Спасибо за помощь.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Гость






Цитата
не могли бы Вы мне объяснить почему именно так работает, а как у меня нет?
Могли бы... smile.gif Внимательнее надо быть:
Цитата
	else
{
//NewMenu := TMenuItem.Create(menu);
NewSubMenu = new TMenuItem(menu); // Чего создали? NewSubMenu
NewMenu->Caption = TVnode->Text; // А обращаемся к чему? К NewMenu, а там - мусор...
menu->Add(NewMenu);
}

 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Пионер
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской
Реальное имя: Александр

Репутация: -  0  +


мде) что-то я совсем невнимательный ((( спасибо еще раз.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Пионер
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской
Реальное имя: Александр

Репутация: -  0  +


Возникла еще такая проблема: необходимо сделать так, чтобы при выделении определенной ветки дерева TreeView менялся значок выделенной ветки. Когда добавляю только родительские ветки все работает нормально, а с дочерними проблема, причем если добавить дочерние ветки, а затем выделить родительские которые находятся по уровню ниже, значок меняется совсем в друном месте.


Пробывал сделать таким образом, работает неверно
void __fastcall TForm1::TreeView1Click(TObject *Sender)
{

TreeView1->Items->Item[TreeView1->Selected->Index]->ImageIndex = 2;

}



и так тоже не верно...
void __fastcall TForm1::TreeView1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift,
int X, int Y)
{
TTreeNode *clickedNode;

clickedNode = TreeView1->GetNodeAt(X,Y);

if (clickedNode != NULL)
{
TreeView1->Items->Item[clickedNode->Index]->ImageIndex = 2;

}

}
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Гость






Цитата
таким образом, работает неверно

Цитата
и так тоже не верно...
Глупостями не занимайся... Тебе достаточно только в самом начале назначить для ВСЕХ узлов ImageIndex и SelectedIndex, а дальше - это уже забота TreeView, как при изменении выбранного элемента его правильно отобразить... Смотри:

void __fastcall TForm1::FormCreate(TObject *Sender)
{
for(int i = 0; i < TreeView1->Items->Count; i++)
{
TreeView1->Items->Item[i]->ImageIndex = 0; // Неактивный Node
TreeView1->Items->Item[i]->SelectedIndex = 1; // Активный Node
}
}

Магия, правда? Теперь запускаешь программу, и все работает (все остальные обработчики, которыми ты пытался колдовать с SelectedItem/ImageIndex надо убрать, они не нужны теперь...)

Кстати, можно каждому узлу вообще назначить свою картинку прямо там же, еще до отображения дерева, можно сказать, что картинку отображать не надо (ImageIndex = -1), все, что угодно...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Пионер
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской
Реальное имя: Александр

Репутация: -  0  +


В том то и дело, что я хотел сделать чтобы пользователь мог сам выбрать картинку, т.е. кликнув по ветке, затем выбрав картинку, она должна появиться в выбранной ветке. Прошу прощения за неверно поставленный вопрос.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Гость






И все равно - не вижу проблемы: Ну, выбрал элемент. Назначил ему какую-то картинку (откуда - это я сам должен догадаться? Тогда все просто: с диска, да, выбрал и записал в ImageList, тут же последний индекс из ImageList-а присвоил в TreeView1->Selected->SelectedIndex). Дальше что? Хоть засоздавайся потом новыми узлами - те, что ужа были назначены (если правильно создавать новые) менять свои изображения не будут. Не веришь?

Прикрепленное изображение

Сначала было добавлено изображение на узел с текстом "12", потом к лежащему выше узлу "11" было добавлено 6 потомков ("adding"), одному из них я опять же сменил картинку, и ПЕРЕД ним опять добавил 3 потомка узлу... Как видишь - ничего не сбилось...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Пионер
**

Группа: Пользователи
Сообщений: 103
Пол: Мужской
Реальное имя: Александр

Репутация: -  0  +


Владимир очередной раз говорю Вам огромное спасибо, все отлично работает, я как обычно не внимательный, сам себе все усложняю.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 29.04.2024 15:54
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name