TreeView - нужна помощь

posta

Member
Joined
Dec 21, 2004
Messages
15
Reaction score
0
Age
41
Location
Екатеринбург
Ребята, подскажите, плз, как к дереву TreeView (к его пунктам и подпунктам) привязать определенную информацию, например, при выборе конкретного пункта, отображается конкретная информация в Memo..
 

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,104
Reaction score
902
Age
25
TreeView1.Items[n].Data
 

Unsiker

Member
Joined
Feb 19, 2007
Messages
40
Reaction score
0
Age
40
Location
lol
Надо использовать событие OnChange.

в процедуре пишеш:
Memo1.Lines.Clear; // Очищаем Memo от всего написаного(по желанию)
Memo1.Lines.Add(Node.Text) ; // добавляем в Memo заголовок выбраного пункта


в вакуме это должно выглядеть примерно так:

procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
Memo1.Lines.Clear;
Memo1.Lines.Add(Node.Text) ;
end;
 

Unsiker

Member
Joined
Feb 19, 2007
Messages
40
Reaction score
0
Age
40
Location
lol
А теперь по существу

procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
Memo1.Lines.Clear;
if (node.Text = 'заголовок 1') then Memo1.Lines.Add('Пиши что хочеш 1');
if (node.Text = 'заголовок 2') then Memo1.Lines.Add('Пиши что хочеш 2'');
...
if (node.Text = 'заголовок n') then Memo1.Lines.Add('Пиши что хочеш n'');
end;

// тут заголовок 1, заголовок 2,..., заголовок n - названия пунктов меню :cool:
 

ploki

Member
Joined
May 16, 2005
Messages
237
Reaction score
180
Location
Москва
Проверка названий пунктов меню - это мощно! Но концептуально ошибочно.

Если нужно решение под сложную задачу, расширяемое и с минимумом лишнего кода и возможных ошибок, то надо не насиловать язык, а плыть в русле его идеологии. Один из вариантов ниже.

Если разнообразие типов узлов мало, то организуешь иерархию классов с общим предком, ну например, TBaseSincObject и методом Sinc с полиморфным поведением. В каждом подклассе инкапсулируешь всю работу по синхронизации представления с моделью данных (парадигма MVC).

Затем при создании узла дерева (пусть оно называется Tree) сохраняешь ссылку на объект Obj нужного подкласса TBaseSincClass:
Code:
var
  Obj: TSubSincClass; // Потомок TBaseSincClass
  Node: TTreeNode; // Текущий узел дерева

begin
... 
Node.Data := Obj;
...
end;

Тогда обработчик события OnChange становится тривиальным и не изменяется при развитии программы:
Code:
procedure TForm1.TreeChange(Sender: TObject; Node: TTreeNode);
begin
  (Node.Data as TBaseSincObject).Sinc;
end;

Одна строчка! Всё остальное ушло в полиморфное поведение объектов.

P.S. К слову, полиморфное поведение лучше делать отнюдь не виртуализацией публичного метода (public procedure Sinc; virtual; ). Лучше сделать метод Sinc обычным, а в нём вызвать виртуальный защищённый метод (protected procedure DoSinc; virtual; ).
Простейшая реализация метода Sinc тогда будет выглядеть так:
Code:
procedure TSubSincObject.Sinc;
begin
  DoSinc;
end;
Полное обоснование применения этого стандартного шаблона (Nonvirtual interface pattern) писать лень.
 

AT_X

Member
Joined
May 30, 2006
Messages
26
Reaction score
12
Location
Kazahstan
Делай так:

procedure Form1.ButtonClick1(Sender:TObject);
vat Node:TTreeNode;
begin
Node:=TreeView1.SelectedItem;
if Node.Text = 'MainPage' then //и далее на свое усмотрение ))
end;
 

Unsiker

Member
Joined
Feb 19, 2007
Messages
40
Reaction score
0
Age
40
Location
lol
полиморфное поведение объектов.
Если разнообразие типов узлов мало, то организуешь иерархию классов с общим предком, ну например, TBaseSincObject и методом Sinc с полиморфным поведением. В каждом подклассе инкапсулируешь всю работу по синхронизации представления с моделью данных (парадигма MVC).

Не слишком ли доходчиво написано для малыша который даже не знает как к дереву TreeView (к его пунктам и подпунктам) привязать определенную информацию???
 

ploki

Member
Joined
May 16, 2005
Messages
237
Reaction score
180
Location
Москва
Навигация с использованием дерева выдаёт не мальчика, но мужа :)

Непонятно - спросит, ненужно - никто не заставляет так делать, главное - показать, что приведённый в 4 посте пример - не оптимален, и что решая одну проблему, порождает много других (и что есть такое понятие - стиль). К 3 посту никаких притензий - хороший начальный пример.

Захочет человек развиваться - поймёт основные концепции ООП.
Вполне понятно поведение классов описано в http://www.delphikingdom.ru/lyceum/seminar.asp?id=6 (глава 3).

По стилю рекомендую почитать CODE COMPLETE (в русском переводе - "совершенный код").

P.S. Показать глубину некоторой предметной области всегда полезно (IMHO).

P.S.2. Кстати, стандартный TTreeView - очень ограниченный компонент. Есть шедевр (бесплатный) - TVirtualTreeView (http://www.delphi-gems.com/VirtualTreeview/). На будущее, только на будущее!
 
Last edited by a moderator:

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,104
Reaction score
902
Age
25
Вопрос к небожителям в области паскаля. А чем же концептуально неправильно использование свойства Data. Просто для банальных целей привязвания текстовой информации к итему дерева я бы использовал строчный массив и в Data бросал его индекс. А дальше, выводил бы в нужную часть интерфейса нужный текст ... Вопрос - в чем ущербность такого подхода.
 

ploki

Member
Joined
May 16, 2005
Messages
237
Reaction score
180
Location
Москва
to Ognev

Это как раз правильно (пост №2 нёс максимум информации на символ :) ). Ущербности не наблюдается.
Неправильно использовать для связи текст узла. Например, что нужно было бы сделать при локализации программы?
 
Top